From 8255dfd9960c2854d1bb44d1177fff1afc45a665 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Thu, 13 Oct 2011 09:07:37 -0300 Subject: [PATCH 1/6] Added handle_resource_conflict_response feature to handle 409 reponse, Cosmetic. --- .../restbucks/src/domain/order_validation.e | 1 - .../restbucks/src/resource/order_handler.e | 119 +++++++++++++----- .../misc/request_resource_handler_helper.e | 19 +++ 3 files changed, 104 insertions(+), 35 deletions(-) diff --git a/examples/restbucks/src/domain/order_validation.e b/examples/restbucks/src/domain/order_validation.e index d4bd39b9..b3b1842d 100644 --- a/examples/restbucks/src/domain/order_validation.e +++ b/examples/restbucks/src/domain/order_validation.e @@ -50,7 +50,6 @@ feature -- Access end end - note copyright: "2011-2011, Javier Velilla and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/examples/restbucks/src/resource/order_handler.e b/examples/restbucks/src/resource/order_handler.e index 75f0fe5d..aa9dd712 100644 --- a/examples/restbucks/src/resource/order_handler.e +++ b/examples/restbucks/src/resource/order_handler.e @@ -1,5 +1,5 @@ note - description: "Summary description for {ORDER_HANDLER}." + description: "{ORDER_HANDLER} handle the resources that we want to expose" author: "" date: "$Date$" revision: "$Revision$" @@ -74,68 +74,97 @@ feature -- HTTP Methods end do_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + -- Updating a resource with PUT + -- A successful PUT request will not create a new resource, instead it will + -- change the state of the resource identified by the current uri. + -- If success we response with 200 and the updated order. + -- 404 if the order is not found + -- 400 in case of a bad request + -- 500 internal server error local l_post: STRING - l_location : STRING l_order : detachable ORDER - h : EWF_HEADER do - fixme ("TODO handle an Internal Server Error") - fixme ("Refactor the code, create new abstractions") - fixme ("Add Header Date to the response") - fixme ("Put implementation is wrong!!!!") req.input.read_stream (req.content_length_value.as_integer_32) l_post := req.input.last_string l_order := extract_order_request(l_post) - fixme ("TODO move to a service method") if l_order /= Void and then db_access.orders.has_key (l_order.id) then - update_order( l_order) - create h.make - h.put_status ({HTTP_STATUS_CODE}.ok) - h.put_content_type ("application/json") - if attached req.request_time as time then - h.add_header ("Date:" +time.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT") - end - if attached req.http_host as host then - l_location := "http://"+host +req.request_uri+"/" + l_order.id - h.add_header ("Location:"+ l_location) - end - if attached {JSON_VALUE} json.value (l_order) as jv then - h.put_content_length (jv.representation.count) - res.set_status_code ({HTTP_STATUS_CODE}.ok) - res.write_headers_string (h.string) - res.write_string (jv.representation) + if is_valid_to_update(l_order) then + update_order( l_order) + compute_response_put (ctx, req, res, l_order) + else + --| FIXME: Here we need to define the Allow methods + handle_resource_conflict_response (l_post +"%N There is conflict while trying to update the order, the order could not be update in the current state", ctx, req, res) end else handle_bad_request_response (l_post +"%N is not a valid ORDER, maybe the order does not exist in the system", ctx, req, res) end end + compute_response_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) + local + h: EWF_HEADER + joc : JSON_ORDER_CONVERTER + do + create h.make + create joc.make + json.add_converter(joc) + + create h.make + h.put_status ({HTTP_STATUS_CODE}.ok) + h.put_content_type_application_json + if attached req.request_time as time then + h.add_header ("Date:" +time.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT") + end + if attached {JSON_VALUE} json.value (l_order) as jv then + h.put_content_length (jv.representation.count) + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.write_headers_string (h.string) + res.write_string (jv.representation) + end + end + + do_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + -- Here we use DELETE to cancel an order, if that order is in state where + -- it can still be canceled. + -- 200 if is ok + -- 409 if consumer and service's view of the resouce state is inconsisent + -- 500 if we have an internal server error local id: STRING h : EWF_HEADER do - fixme ("TODO handle an Internal Server Error") - fixme ("Refactor the code, create new abstractions") if attached req.orig_path_info as orig_path then id := get_order_id_from_path (orig_path) if db_access.orders.has_key (id) then - delete_order( id) - create h.make - h.put_status ({HTTP_STATUS_CODE}.no_content) - h.put_content_type ("application/json") - if attached req.request_time as time then - h.put_utc_date (time) + if is_valid_to_delete (id) then + delete_order( id) + compute_response_delete (ctx, req, res) + else + --| FIXME: Here we need to define the Allow methods + handle_resource_conflict_response (orig_path + "%N There is conflict while trying to delete the order, the order could not be deleted in the current state", ctx, req, res) end - res.set_status_code ({HTTP_STATUS_CODE}.no_content) - res.write_headers_string (h.string) else handle_resource_not_found_response (orig_path + " not found in this server", ctx, req, res) end end end + compute_response_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + local + h: EWF_HEADER + do + create h.make + h.put_status ({HTTP_STATUS_CODE}.no_content) + h.put_content_type_application_json + if attached req.request_time as time then + h.put_utc_date (time) + end + res.set_status_code ({HTTP_STATUS_CODE}.no_content) + res.write_headers_string (h.string) + end + do_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) -- Here the convention is the following. -- POST is used for creation and the server determines the URI @@ -221,6 +250,28 @@ feature {NONE} -- Implementation Repository Layer db_access.orders.force (an_order, an_order.id) end + + is_valid_to_delete ( an_id : STRING) : BOOLEAN + -- Is the order identified by `an_id' in a state whre it can still be deleted? + do + if attached retrieve_order (an_id) as l_order then + if order_validation.is_state_valid_to_update (l_order.status) then + Result := True + end + end + end + + is_valid_to_update (an_order: ORDER) : BOOLEAN + -- Check if there is a conflict while trying to update the order + do + if attached retrieve_order (an_order.id) as l_order then + if order_validation.is_state_valid_to_update (l_order.status) and then order_validation.is_valid_status_state (an_order.status) and then + order_validation.is_valid_transition (l_order, an_order.status) then + Result := True + end + end + end + update_order (an_order: ORDER) -- update the order to the repository do diff --git a/library/server/request/router/src/misc/request_resource_handler_helper.e b/library/server/request/router/src/misc/request_resource_handler_helper.e index f106b16f..d74e7eea 100644 --- a/library/server/request/router/src/misc/request_resource_handler_helper.e +++ b/library/server/request/router/src/misc/request_resource_handler_helper.e @@ -238,6 +238,25 @@ feature -- Handle responses res.write_string (a_description) end + + handle_resource_conflict_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + local + h : EWF_HEADER + do + create h.make + h.put_status ({HTTP_STATUS_CODE}.conflict) + if attached ctx.request_content_type (supported_content_types) as l_content_type then + h.put_content_type (l_content_type) + else + h.put_content_type ("*/*") + end + h.put_content_length (a_description.count) + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.conflict) + res.write_headers_string (h.string) + res.write_string (a_description) + end + note copyright: "2011-2011, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" From 9f532872269168e4854bcfcc1f37b98c869df31f Mon Sep 17 00:00:00 2001 From: jvelilla Date: Fri, 21 Oct 2011 08:26:14 -0300 Subject: [PATCH 2/6] Update Restbucks example: Conditional GET, PUT. Added a response method to support resource not modified. Added a ETAG_UTILS class to calcule md5_digest. Added ext libs eel and eapml. --- .gitmodules | 6 ++ examples/restbucks/restbucks-safe.ecf | 3 +- examples/restbucks/src/domain/order.e | 3 + .../restbucks/src/resource/order_handler.e | 59 +++++++++++++++++-- .../misc/request_resource_handler_helper.e | 39 ++++++++++++ 5 files changed, 105 insertions(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index ad9fdb20..5f591df5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,9 @@ [submodule "ext/ise_library/curl"] path = ext/ise_library/curl url = http://github.com/EiffelSoftware/mirror-Eiffel-cURL.git +[submodule "ext/crypto/eel"] + path = ext/crypto/eel + url = http://github.com/Eiffel-World/eel.git +[submodule "ext/crypto/eapml"] + path = ext/crypto/eapml + url = http://github.com/Eiffel-World/eapml.git diff --git a/examples/restbucks/restbucks-safe.ecf b/examples/restbucks/restbucks-safe.ecf index 4651633a..6ed4fa57 100644 --- a/examples/restbucks/restbucks-safe.ecf +++ b/examples/restbucks/restbucks-safe.ecf @@ -16,8 +16,9 @@ - + + diff --git a/examples/restbucks/src/domain/order.e b/examples/restbucks/src/domain/order.e index d7092a5f..490139ce 100644 --- a/examples/restbucks/src/domain/order.e +++ b/examples/restbucks/src/domain/order.e @@ -86,6 +86,9 @@ feature -- Etag Result := hash_code.out + revision.out end + +feature -- Output + feature -- Report hash_code: INTEGER_32 diff --git a/examples/restbucks/src/resource/order_handler.e b/examples/restbucks/src/resource/order_handler.e index aa9dd712..b2abf8bc 100644 --- a/examples/restbucks/src/resource/order_handler.e +++ b/examples/restbucks/src/resource/order_handler.e @@ -40,25 +40,48 @@ feature -- HTTP Methods -- 200 OK, and a representation of the order -- If the GET request is not SUCCESS, we response with -- 404 Resource not found + -- If is a Condition GET and the resource does not change we send a + -- 304, Resource not modifed local id : STRING do if attached req.orig_path_info as orig_path then id := get_order_id_from_path (orig_path) if attached retrieve_order (id) as l_order then - compute_response_get (ctx, req, res, l_order) + if is_conditional_get (req, l_order) then + handle_resource_not_modified_response ("The resource" + orig_path + "does not change", ctx, req, res) + else + compute_response_get (ctx, req, res, l_order) + end else handle_resource_not_found_response ("The following resource" + orig_path + " is not found ", ctx, req, res) end end end + is_conditional_get (req : WGI_REQUEST; l_order : ORDER) : BOOLEAN + -- Check if If-None-Match is present and then if there is a representation that has that etag + -- if the representation hasn't changed, we return TRUE + -- then the response is a 304 with no entity body returned. + local + etag_util : ETAG_UTILS + do + if attached req.meta_variable ("HTTP_IF_NONE_MATCH") as if_none_match then + create etag_util + if if_none_match.as_string.same_string (etag_util.md5_digest (l_order.out).as_string_32) then + Result := True + end + end + end + compute_response_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) local h: EWF_HEADER l_msg : STRING + etag_utils : ETAG_UTILS do create h.make + create etag_utils h.put_status ({HTTP_STATUS_CODE}.ok) h.put_content_type_application_json if attached {JSON_VALUE} json.value (l_order) as jv then @@ -67,6 +90,7 @@ feature -- HTTP Methods if attached req.request_time as time then h.add_header ("Date:" + time.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT") end + h.add_header ("etag:" + etag_utils.md5_digest (l_order.out)) res.set_status_code ({HTTP_STATUS_CODE}.ok) res.write_headers_string (h.string) res.write_string (l_msg) @@ -81,6 +105,8 @@ feature -- HTTP Methods -- 404 if the order is not found -- 400 in case of a bad request -- 500 internal server error + -- If the request is a Conditional PUT, and it does not mat we response + -- 415, precondition failed. local l_post: STRING l_order : detachable ORDER @@ -90,8 +116,12 @@ feature -- HTTP Methods l_order := extract_order_request(l_post) if l_order /= Void and then db_access.orders.has_key (l_order.id) then if is_valid_to_update(l_order) then - update_order( l_order) - compute_response_put (ctx, req, res, l_order) + if is_conditional_put (req, l_order) then + update_order( l_order) + compute_response_put (ctx, req, res, l_order) + else + handle_precondition_fail_response ("", ctx, req, res) + end else --| FIXME: Here we need to define the Allow methods handle_resource_conflict_response (l_post +"%N There is conflict while trying to update the order, the order could not be update in the current state", ctx, req, res) @@ -101,13 +131,34 @@ feature -- HTTP Methods end end + is_conditional_put (req : WGI_REQUEST; order : ORDER) : BOOLEAN + -- Check if If-Match is present and then if there is a representation that has that etag + -- if the representation hasn't changed, we return TRUE + local + etag_util : ETAG_UTILS + do + if attached retrieve_order (order.id) as l_order then + if attached req.meta_variable ("HTTP_IF_MATCH") as if_match then + create etag_util + if if_match.as_string.same_string (etag_util.md5_digest (l_order.out).as_string_32) then + Result := True + end + else + Result := True + end + end + end + + compute_response_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) local h: EWF_HEADER joc : JSON_ORDER_CONVERTER + etag_utils : ETAG_UTILS do create h.make create joc.make + create etag_utils json.add_converter(joc) create h.make @@ -116,6 +167,7 @@ feature -- HTTP Methods if attached req.request_time as time then h.add_header ("Date:" +time.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT") end + h.add_header ("etag:" + etag_utils.md5_digest (l_order.out)) if attached {JSON_VALUE} json.value (l_order) as jv then h.put_content_length (jv.representation.count) res.set_status_code ({HTTP_STATUS_CODE}.ok) @@ -133,7 +185,6 @@ feature -- HTTP Methods -- 500 if we have an internal server error local id: STRING - h : EWF_HEADER do if attached req.orig_path_info as orig_path then id := get_order_id_from_path (orig_path) diff --git a/library/server/request/router/src/misc/request_resource_handler_helper.e b/library/server/request/router/src/misc/request_resource_handler_helper.e index d74e7eea..31bff168 100644 --- a/library/server/request/router/src/misc/request_resource_handler_helper.e +++ b/library/server/request/router/src/misc/request_resource_handler_helper.e @@ -182,6 +182,25 @@ feature -- Handle responses res.write_string (a_description) end + + handle_precondition_fail_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + local + h : EWF_HEADER + do + create h.make + h.put_status ({HTTP_STATUS_CODE}.precondition_failed) + if attached ctx.request_content_type (supported_content_types) as l_content_type then + h.put_content_type (l_content_type) + else + h.put_content_type ("*/*") + end + h.put_content_length (a_description.count) + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.precondition_failed) + res.write_headers_string (h.string) + res.write_string (a_description) + end + handle_internal_server_error (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) local h : EWF_HEADER @@ -239,6 +258,26 @@ feature -- Handle responses end + handle_resource_not_modified_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + local + h : EWF_HEADER + do + res.flush + create h.make + h.put_status ({HTTP_STATUS_CODE}.not_modified) + if attached ctx.request_content_type (supported_content_types) as l_content_type then + h.put_content_type (l_content_type) + else + h.put_content_type ("*/*") + end + h.put_content_length (a_description.count) + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.not_modified) + res.write_headers_string (h.string) + res.write_string (a_description) + end + + handle_resource_conflict_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) local h : EWF_HEADER From 6344f964fa8f96bd19520c145e3988d268ad4d04 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 23 Oct 2011 09:05:12 -0300 Subject: [PATCH 3/6] Update delete method to hanlde method not allowed. Added method not allowed to request resource handler helper class. Update gitmodules --- .gitmodules | 5 ----- examples/restbucks/src/resource/order_handler.e | 5 +++-- .../src/misc/request_resource_handler_helper.e | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5f591df5..8cea3766 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,8 +11,3 @@ path = ext/ise_library/curl url = http://github.com/EiffelSoftware/mirror-Eiffel-cURL.git [submodule "ext/crypto/eel"] - path = ext/crypto/eel - url = http://github.com/Eiffel-World/eel.git -[submodule "ext/crypto/eapml"] - path = ext/crypto/eapml - url = http://github.com/Eiffel-World/eapml.git diff --git a/examples/restbucks/src/resource/order_handler.e b/examples/restbucks/src/resource/order_handler.e index b2abf8bc..1de6731f 100644 --- a/examples/restbucks/src/resource/order_handler.e +++ b/examples/restbucks/src/resource/order_handler.e @@ -181,7 +181,8 @@ feature -- HTTP Methods -- Here we use DELETE to cancel an order, if that order is in state where -- it can still be canceled. -- 200 if is ok - -- 409 if consumer and service's view of the resouce state is inconsisent + -- 404 Resource not found + -- 405 if consumer and service's view of the resouce state is inconsisent -- 500 if we have an internal server error local id: STRING @@ -194,7 +195,7 @@ feature -- HTTP Methods compute_response_delete (ctx, req, res) else --| FIXME: Here we need to define the Allow methods - handle_resource_conflict_response (orig_path + "%N There is conflict while trying to delete the order, the order could not be deleted in the current state", ctx, req, res) + handle_method_not_allowed_response (orig_path + "%N There is conflict while trying to delete the order, the order could not be deleted in the current state", ctx, req, res) end else handle_resource_not_found_response (orig_path + " not found in this server", ctx, req, res) diff --git a/library/server/request/router/src/misc/request_resource_handler_helper.e b/library/server/request/router/src/misc/request_resource_handler_helper.e index 31bff168..c852085c 100644 --- a/library/server/request/router/src/misc/request_resource_handler_helper.e +++ b/library/server/request/router/src/misc/request_resource_handler_helper.e @@ -239,6 +239,23 @@ feature -- Handle responses res.write_string (a_description) end + handle_method_not_allowed_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) + local + h : EWF_HEADER + do + create h.make + h.put_status ({HTTP_STATUS_CODE}.method_not_allowed) + if attached ctx.request_content_type (supported_content_types) as l_content_type then + h.put_content_type (l_content_type) + else + h.put_content_type ("*/*") + end + h.put_content_length (a_description.count) + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed) + res.write_headers_string (h.string) + res.write_string (a_description) + end handle_resource_not_found_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) local h : EWF_HEADER From 3fbd81aeb176677d43be1b2593389c036aa291ea Mon Sep 17 00:00:00 2001 From: jvelilla Date: Sun, 23 Oct 2011 09:10:27 -0300 Subject: [PATCH 4/6] Added eel and eapml modules --- .gitmodules | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitmodules b/.gitmodules index 8cea3766..92276b15 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,3 +11,9 @@ path = ext/ise_library/curl url = http://github.com/EiffelSoftware/mirror-Eiffel-cURL.git [submodule "ext/crypto/eel"] +[submodule "ext/crypto/eel"] + path = ext/crypto/eel + url = http://github.com/Eiffel-World/eel.git +[submodule "ext/crypto/eapml"] + path = ext/crypto/eapml + url = http://github.com/Eiffel-World/eapml.git From f804a705d56a89edb6d97253c6027f4b09da0ad7 Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 26 Oct 2011 08:21:50 -0300 Subject: [PATCH 5/6] Updated request resource handler. TODO: implement Content-Negotiation --- .../misc/request_resource_handler_helper.e | 55 ++++--------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/library/server/request/router/src/misc/request_resource_handler_helper.e b/library/server/request/router/src/misc/request_resource_handler_helper.e index 9741111d..1fb5b73c 100644 --- a/library/server/request/router/src/misc/request_resource_handler_helper.e +++ b/library/server/request/router/src/misc/request_resource_handler_helper.e @@ -156,7 +156,10 @@ feature -- Method Extension Method end feature -- Handle responses - + -- TODO Handle Content negotiation. + -- The option : Server-driven negotiation: uses request headers to select a variant + -- More info : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12 + supported_content_types: detachable ARRAY [READABLE_STRING_8] -- Supported content types -- Can be redefined @@ -170,11 +173,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.bad_request) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.bad_request) @@ -189,11 +188,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.precondition_failed) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.precondition_failed) @@ -207,13 +202,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.internal_server_error) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - --| FIXME: I guess it should be plain/text , - --| */* sounds more for Accept header in request - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) @@ -227,11 +216,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.not_implemented) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.not_implemented) @@ -245,11 +230,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.method_not_allowed) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed) @@ -263,11 +244,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.not_found) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.not_found) @@ -283,11 +260,7 @@ feature -- Handle responses res.flush create h.make h.put_status ({HTTP_STATUS_CODE}.not_modified) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.not_modified) @@ -302,11 +275,7 @@ feature -- Handle responses do create h.make h.put_status ({HTTP_STATUS_CODE}.conflict) - if attached ctx.request_content_type (supported_content_types) as l_content_type then - h.put_content_type (l_content_type) - else - h.put_content_type ("*/*") - end + h.put_content_type_application_json h.put_content_length (a_description.count) h.put_current_date res.set_status_code ({HTTP_STATUS_CODE}.conflict) From c9343688f3426e1c4044815a9569cb382141212a Mon Sep 17 00:00:00 2001 From: jvelilla Date: Thu, 27 Oct 2011 08:29:01 -0300 Subject: [PATCH 6/6] Added eel and eapml in EWF libraries. Removed them from gitmodule --- .gitmodules | 7 - examples/restbucks/restbucks-safe.ecf | 2 +- ext/crypto/eapml | 1 - ext/crypto/eel | 1 - library/crypto/eapml/.gitignore | 1 + .../eapml/bit_scan_gcc/limb_bit_scanning.e | 59 + .../eapml/bit_scan_vc/limb_bit_scanning.e | 59 + library/crypto/eapml/divide_by_zero.e | 19 + library/crypto/eapml/eapml-safe.ecf | 50 + library/crypto/eapml/eapml.ecf | 50 + .../facilities/case_insensitive_strategy.e | 224 ++ .../facilities/case_sensitive_strategy.e | 276 +++ .../eapml/facilities/character_strategy.e | 20 + .../eapml/facilities/integer_x_access.e | 77 + .../eapml/facilities/integer_x_arithmetic.e | 914 +++++++++ .../eapml/facilities/integer_x_assignment.e | 155 ++ .../eapml/facilities/integer_x_comparison.e | 200 ++ .../eapml/facilities/integer_x_division.e | 429 ++++ .../eapml/facilities/integer_x_facilities.e | 11 + .../crypto/eapml/facilities/integer_x_gcd.e | 145 ++ .../crypto/eapml/facilities/integer_x_io.e | 335 +++ .../crypto/eapml/facilities/integer_x_logic.e | 1037 ++++++++++ .../facilities/integer_x_number_theory.e | 967 +++++++++ .../eapml/facilities/integer_x_random.e | 108 + .../eapml/facilities/integer_x_sizing.e | 49 + library/crypto/eapml/facilities/mp_bases.e | 1603 +++++++++++++++ library/crypto/eapml/facilities/powers.e | 32 + .../crypto/eapml/facilities/rand_lc_struct.e | 44 + .../crypto/eapml/facilities/special_access.e | 262 +++ .../eapml/facilities/special_arithmetic.e | 1022 ++++++++++ .../eapml/facilities/special_assignment.e | 159 ++ .../eapml/facilities/special_comparison.e | 39 + .../eapml/facilities/special_division.e | 1102 ++++++++++ library/crypto/eapml/facilities/special_gcd.e | 1103 ++++++++++ .../crypto/eapml/facilities/special_logic.e | 332 +++ .../facilities/special_number_theoretic.e | 849 ++++++++ .../crypto/eapml/facilities/special_sizing.e | 52 + .../crypto/eapml/facilities/special_utility.e | 37 + library/crypto/eapml/immutable_integer_x.e | 66 + library/crypto/eapml/integer_x.e | 89 + .../crypto/eapml/integer_x_string_exception.e | 20 + library/crypto/eapml/inverse_exception.e | 19 + .../eapml/limb_natural_32/limb_definition.e | 17 + .../eapml/limb_natural_32/limb_manipulation.e | 458 +++++ .../crypto/eapml/linear_congruential_rng.e | 249 +++ library/crypto/eapml/mersenne_twister_rng.e | 1490 ++++++++++++++ .../crypto/eapml/random_number_generator.e | 28 + library/crypto/eapml/readable_integer_x.e | 1741 ++++++++++++++++ library/crypto/eapml/tests/TODO.txt | 37 + library/crypto/eapml/tests/test.e | 43 + .../eapml/tests/test_integer_functions.e | 19 + library/crypto/eapml/tests/test_integer_x.e | 557 +++++ .../eapml/tests/test_integer_x_access.e | 395 ++++ .../eapml/tests/test_integer_x_arithmetic.e | 208 ++ .../eapml/tests/test_integer_x_assignment.e | 217 ++ .../eapml/tests/test_integer_x_division.e | 32 + .../crypto/eapml/tests/test_integer_x_gcd.e | 92 + .../crypto/eapml/tests/test_integer_x_io.e | 89 + .../crypto/eapml/tests/test_integer_x_logic.e | 126 ++ .../tests/test_integer_x_number_theory.e | 266 +++ .../eapml/tests/test_integer_x_random.e | 82 + .../eapml/tests/test_limb_manipulation.e | 37 + .../crypto/eapml/tests/test_randstruct_lc.e | 85 + .../crypto/eapml/tests/test_randstruct_mt.e | 46 + .../eapml/tests/test_special_arithmetic.e | 463 +++++ .../eapml/tests/test_special_division.e | 458 +++++ library/crypto/eapml/tests/test_special_gcd.e | 446 ++++ .../crypto/eapml/tests/test_special_logic.e | 252 +++ .../tests/test_special_number_theoretic.e | 146 ++ library/crypto/eapml/tests/tests-safe.ecf | 25 + library/crypto/eapml/tests/tests.ecf | 29 + library/crypto/eapml/tests/tests.rc | 1 + library/crypto/eel/.gitignore | 1 + library/crypto/eel/RSA/rsa_key_pair.e | 62 + library/crypto/eel/RSA/rsa_private_key.e | 46 + library/crypto/eel/RSA/rsa_public_key.e | 43 + library/crypto/eel/aes/aes_common.e | 150 ++ library/crypto/eel/aes/aes_engine.e | 531 +++++ library/crypto/eel/aes/aes_key.e | 758 +++++++ library/crypto/eel/array_facilities.e | 148 ++ .../crypto/eel/byte_32_bit_block_facilities.e | 56 + .../crypto/eel/byte_64_bit_block_facilities.e | 19 + library/crypto/eel/byte_facilities.e | 85 + library/crypto/eel/constants.e | 36 + library/crypto/eel/der/array_der_sink.e | 29 + library/crypto/eel/der/array_der_source.e | 44 + library/crypto/eel/der/der_encodable.e | 18 + library/crypto/eel/der/der_encoding.e | 24 + library/crypto/eel/der/der_facilities.e | 196 ++ library/crypto/eel/der/der_octet_sink.e | 15 + library/crypto/eel/der/der_octet_source.e | 27 + .../crypto/eel/der/der_universal_class_tag.e | 31 + library/crypto/eel/digests/MD5/md5.e | 283 +++ library/crypto/eel/digests/SHA1/sha1.e | 346 ++++ library/crypto/eel/digests/SHA256/sha256.e | 363 ++++ library/crypto/eel/digests/sha_functions.e | 118 ++ .../crypto/eel/digests/sha_functions.e.orig | 118 ++ library/crypto/eel/ec/ec_constants.e | 14 + library/crypto/eel/ec/ec_curve.e | 23 + library/crypto/eel/ec/ec_curve_f2m.e | 419 ++++ library/crypto/eel/ec/ec_curve_fp.e | 230 +++ library/crypto/eel/ec/ec_domain_parameters.e | 44 + .../crypto/eel/ec/ec_domain_parameters.e.orig | 44 + .../crypto/eel/ec/ec_domain_parameters_f2m.e | 279 +++ .../crypto/eel/ec/ec_domain_parameters_fp.e | 214 ++ library/crypto/eel/ec/ec_field_element.e | 134 ++ library/crypto/eel/ec/ec_field_element_f2m.e | 518 +++++ library/crypto/eel/ec/ec_field_element_fp.e | 214 ++ library/crypto/eel/ec/ec_key_pair.e | 334 +++ library/crypto/eel/ec/ec_key_parameters.e | 13 + library/crypto/eel/ec/ec_point.e | 122 ++ library/crypto/eel/ec/ec_point_f2m.e | 593 ++++++ library/crypto/eel/ec/ec_point_fp.e | 481 +++++ library/crypto/eel/ec/ec_private_key.e | 89 + library/crypto/eel/ec/ec_public_key.e | 74 + library/crypto/eel/ec/f2m_representations.e | 18 + library/crypto/eel/ec/standard_curves.e | 1807 +++++++++++++++++ library/crypto/eel/eel-safe.ecf | 26 + library/crypto/eel/eel.ecf | 25 + library/crypto/eel/eel.ecf.orig | 23 + library/crypto/eel/hmac/hmac_sha256.e | 133 ++ library/crypto/eel/modes/cbc_decryption.e | 58 + library/crypto/eel/modes/cbc_encryption.e | 57 + library/crypto/eel/modes/cbc_target.e | 41 + library/crypto/eel/modes/cfb_decryption.e | 69 + library/crypto/eel/modes/cfb_encryption.e | 69 + library/crypto/eel/modes/cfb_target.e | 31 + library/crypto/eel/modes/ctr_decryption.e | 57 + library/crypto/eel/modes/ctr_encryption.e | 57 + library/crypto/eel/modes/ctr_target.e | 31 + library/crypto/eel/modes/ecb_decryption.e | 44 + library/crypto/eel/modes/ecb_encryption.e | 44 + library/crypto/eel/modes/ecb_target.e | 41 + library/crypto/eel/modes/mode_test_data.e | 45 + library/crypto/eel/modes/ofb_decryption.e | 55 + library/crypto/eel/modes/ofb_encryption.e | 55 + library/crypto/eel/modes/ofb_target.e | 31 + library/crypto/eel/preferences.wb | 1 + library/crypto/eel/rotate_facilities.e | 31 + library/crypto/eel/tests/aes_test.e | 250 +++ library/crypto/eel/tests/cbc_test.e | 226 +++ library/crypto/eel/tests/cfb_test.e | 226 +++ library/crypto/eel/tests/ctr_test.e | 226 +++ library/crypto/eel/tests/der_test.e | 52 + library/crypto/eel/tests/ec_test.e | 407 ++++ library/crypto/eel/tests/ecb_test.e | 227 +++ library/crypto/eel/tests/hmac_sha256_test.e | 110 + library/crypto/eel/tests/md5_test.e | 136 ++ library/crypto/eel/tests/ofb_test.e | 226 +++ library/crypto/eel/tests/rsa_test.e | 89 + library/crypto/eel/tests/sha1_test.e | 169 ++ library/crypto/eel/tests/sha256_test.e | 170 ++ library/crypto/eel/tests/test.e | 95 + library/crypto/eel/tests/test.e.orig | 194 ++ library/crypto/eel/tests/test_ec_binary.e | 493 +++++ .../eel/tests/test_ec_field_element_f2m.e | 14 + library/crypto/eel/tests/tests-safe.ecf | 30 + library/crypto/eel/tests/tests.ecf | 30 + library/crypto/eel/tests/tests.rc | 1 + .../crypto/eel/x509/algorithm_identifier.e | 38 + .../crypto/eel/x509/algorithm_parameters.e | 11 + .../eel/x509/attribute_type_and_value.e | 24 + library/crypto/eel/x509/certificate.e | 29 + library/crypto/eel/x509/extension.e | 26 + library/crypto/eel/x509/name.e | 22 + library/crypto/eel/x509/object_identifier.e | 108 + .../crypto/eel/x509/subject_public_key_info.e | 24 + library/crypto/eel/x509/tbs_certificate.e | 72 + library/crypto/eel/x509/validity.e | 24 + 169 files changed, 34134 insertions(+), 10 deletions(-) delete mode 160000 ext/crypto/eapml delete mode 160000 ext/crypto/eel create mode 100644 library/crypto/eapml/.gitignore create mode 100644 library/crypto/eapml/bit_scan_gcc/limb_bit_scanning.e create mode 100644 library/crypto/eapml/bit_scan_vc/limb_bit_scanning.e create mode 100644 library/crypto/eapml/divide_by_zero.e create mode 100644 library/crypto/eapml/eapml-safe.ecf create mode 100644 library/crypto/eapml/eapml.ecf create mode 100644 library/crypto/eapml/facilities/case_insensitive_strategy.e create mode 100644 library/crypto/eapml/facilities/case_sensitive_strategy.e create mode 100644 library/crypto/eapml/facilities/character_strategy.e create mode 100644 library/crypto/eapml/facilities/integer_x_access.e create mode 100644 library/crypto/eapml/facilities/integer_x_arithmetic.e create mode 100644 library/crypto/eapml/facilities/integer_x_assignment.e create mode 100644 library/crypto/eapml/facilities/integer_x_comparison.e create mode 100644 library/crypto/eapml/facilities/integer_x_division.e create mode 100644 library/crypto/eapml/facilities/integer_x_facilities.e create mode 100644 library/crypto/eapml/facilities/integer_x_gcd.e create mode 100644 library/crypto/eapml/facilities/integer_x_io.e create mode 100644 library/crypto/eapml/facilities/integer_x_logic.e create mode 100644 library/crypto/eapml/facilities/integer_x_number_theory.e create mode 100644 library/crypto/eapml/facilities/integer_x_random.e create mode 100644 library/crypto/eapml/facilities/integer_x_sizing.e create mode 100644 library/crypto/eapml/facilities/mp_bases.e create mode 100644 library/crypto/eapml/facilities/powers.e create mode 100644 library/crypto/eapml/facilities/rand_lc_struct.e create mode 100644 library/crypto/eapml/facilities/special_access.e create mode 100644 library/crypto/eapml/facilities/special_arithmetic.e create mode 100644 library/crypto/eapml/facilities/special_assignment.e create mode 100644 library/crypto/eapml/facilities/special_comparison.e create mode 100644 library/crypto/eapml/facilities/special_division.e create mode 100644 library/crypto/eapml/facilities/special_gcd.e create mode 100644 library/crypto/eapml/facilities/special_logic.e create mode 100644 library/crypto/eapml/facilities/special_number_theoretic.e create mode 100644 library/crypto/eapml/facilities/special_sizing.e create mode 100644 library/crypto/eapml/facilities/special_utility.e create mode 100644 library/crypto/eapml/immutable_integer_x.e create mode 100644 library/crypto/eapml/integer_x.e create mode 100644 library/crypto/eapml/integer_x_string_exception.e create mode 100644 library/crypto/eapml/inverse_exception.e create mode 100644 library/crypto/eapml/limb_natural_32/limb_definition.e create mode 100644 library/crypto/eapml/limb_natural_32/limb_manipulation.e create mode 100644 library/crypto/eapml/linear_congruential_rng.e create mode 100644 library/crypto/eapml/mersenne_twister_rng.e create mode 100644 library/crypto/eapml/random_number_generator.e create mode 100644 library/crypto/eapml/readable_integer_x.e create mode 100644 library/crypto/eapml/tests/TODO.txt create mode 100644 library/crypto/eapml/tests/test.e create mode 100644 library/crypto/eapml/tests/test_integer_functions.e create mode 100644 library/crypto/eapml/tests/test_integer_x.e create mode 100644 library/crypto/eapml/tests/test_integer_x_access.e create mode 100644 library/crypto/eapml/tests/test_integer_x_arithmetic.e create mode 100644 library/crypto/eapml/tests/test_integer_x_assignment.e create mode 100644 library/crypto/eapml/tests/test_integer_x_division.e create mode 100644 library/crypto/eapml/tests/test_integer_x_gcd.e create mode 100644 library/crypto/eapml/tests/test_integer_x_io.e create mode 100644 library/crypto/eapml/tests/test_integer_x_logic.e create mode 100644 library/crypto/eapml/tests/test_integer_x_number_theory.e create mode 100644 library/crypto/eapml/tests/test_integer_x_random.e create mode 100644 library/crypto/eapml/tests/test_limb_manipulation.e create mode 100644 library/crypto/eapml/tests/test_randstruct_lc.e create mode 100644 library/crypto/eapml/tests/test_randstruct_mt.e create mode 100644 library/crypto/eapml/tests/test_special_arithmetic.e create mode 100644 library/crypto/eapml/tests/test_special_division.e create mode 100644 library/crypto/eapml/tests/test_special_gcd.e create mode 100644 library/crypto/eapml/tests/test_special_logic.e create mode 100644 library/crypto/eapml/tests/test_special_number_theoretic.e create mode 100644 library/crypto/eapml/tests/tests-safe.ecf create mode 100644 library/crypto/eapml/tests/tests.ecf create mode 100644 library/crypto/eapml/tests/tests.rc create mode 100644 library/crypto/eel/.gitignore create mode 100644 library/crypto/eel/RSA/rsa_key_pair.e create mode 100644 library/crypto/eel/RSA/rsa_private_key.e create mode 100644 library/crypto/eel/RSA/rsa_public_key.e create mode 100644 library/crypto/eel/aes/aes_common.e create mode 100644 library/crypto/eel/aes/aes_engine.e create mode 100644 library/crypto/eel/aes/aes_key.e create mode 100644 library/crypto/eel/array_facilities.e create mode 100644 library/crypto/eel/byte_32_bit_block_facilities.e create mode 100644 library/crypto/eel/byte_64_bit_block_facilities.e create mode 100644 library/crypto/eel/byte_facilities.e create mode 100644 library/crypto/eel/constants.e create mode 100644 library/crypto/eel/der/array_der_sink.e create mode 100644 library/crypto/eel/der/array_der_source.e create mode 100644 library/crypto/eel/der/der_encodable.e create mode 100644 library/crypto/eel/der/der_encoding.e create mode 100644 library/crypto/eel/der/der_facilities.e create mode 100644 library/crypto/eel/der/der_octet_sink.e create mode 100644 library/crypto/eel/der/der_octet_source.e create mode 100644 library/crypto/eel/der/der_universal_class_tag.e create mode 100644 library/crypto/eel/digests/MD5/md5.e create mode 100644 library/crypto/eel/digests/SHA1/sha1.e create mode 100644 library/crypto/eel/digests/SHA256/sha256.e create mode 100644 library/crypto/eel/digests/sha_functions.e create mode 100644 library/crypto/eel/digests/sha_functions.e.orig create mode 100644 library/crypto/eel/ec/ec_constants.e create mode 100644 library/crypto/eel/ec/ec_curve.e create mode 100644 library/crypto/eel/ec/ec_curve_f2m.e create mode 100644 library/crypto/eel/ec/ec_curve_fp.e create mode 100644 library/crypto/eel/ec/ec_domain_parameters.e create mode 100644 library/crypto/eel/ec/ec_domain_parameters.e.orig create mode 100644 library/crypto/eel/ec/ec_domain_parameters_f2m.e create mode 100644 library/crypto/eel/ec/ec_domain_parameters_fp.e create mode 100644 library/crypto/eel/ec/ec_field_element.e create mode 100644 library/crypto/eel/ec/ec_field_element_f2m.e create mode 100644 library/crypto/eel/ec/ec_field_element_fp.e create mode 100644 library/crypto/eel/ec/ec_key_pair.e create mode 100644 library/crypto/eel/ec/ec_key_parameters.e create mode 100644 library/crypto/eel/ec/ec_point.e create mode 100644 library/crypto/eel/ec/ec_point_f2m.e create mode 100644 library/crypto/eel/ec/ec_point_fp.e create mode 100644 library/crypto/eel/ec/ec_private_key.e create mode 100644 library/crypto/eel/ec/ec_public_key.e create mode 100644 library/crypto/eel/ec/f2m_representations.e create mode 100644 library/crypto/eel/ec/standard_curves.e create mode 100644 library/crypto/eel/eel-safe.ecf create mode 100644 library/crypto/eel/eel.ecf create mode 100644 library/crypto/eel/eel.ecf.orig create mode 100644 library/crypto/eel/hmac/hmac_sha256.e create mode 100644 library/crypto/eel/modes/cbc_decryption.e create mode 100644 library/crypto/eel/modes/cbc_encryption.e create mode 100644 library/crypto/eel/modes/cbc_target.e create mode 100644 library/crypto/eel/modes/cfb_decryption.e create mode 100644 library/crypto/eel/modes/cfb_encryption.e create mode 100644 library/crypto/eel/modes/cfb_target.e create mode 100644 library/crypto/eel/modes/ctr_decryption.e create mode 100644 library/crypto/eel/modes/ctr_encryption.e create mode 100644 library/crypto/eel/modes/ctr_target.e create mode 100644 library/crypto/eel/modes/ecb_decryption.e create mode 100644 library/crypto/eel/modes/ecb_encryption.e create mode 100644 library/crypto/eel/modes/ecb_target.e create mode 100644 library/crypto/eel/modes/mode_test_data.e create mode 100644 library/crypto/eel/modes/ofb_decryption.e create mode 100644 library/crypto/eel/modes/ofb_encryption.e create mode 100644 library/crypto/eel/modes/ofb_target.e create mode 100644 library/crypto/eel/preferences.wb create mode 100644 library/crypto/eel/rotate_facilities.e create mode 100644 library/crypto/eel/tests/aes_test.e create mode 100644 library/crypto/eel/tests/cbc_test.e create mode 100644 library/crypto/eel/tests/cfb_test.e create mode 100644 library/crypto/eel/tests/ctr_test.e create mode 100644 library/crypto/eel/tests/der_test.e create mode 100644 library/crypto/eel/tests/ec_test.e create mode 100644 library/crypto/eel/tests/ecb_test.e create mode 100644 library/crypto/eel/tests/hmac_sha256_test.e create mode 100644 library/crypto/eel/tests/md5_test.e create mode 100644 library/crypto/eel/tests/ofb_test.e create mode 100644 library/crypto/eel/tests/rsa_test.e create mode 100644 library/crypto/eel/tests/sha1_test.e create mode 100644 library/crypto/eel/tests/sha256_test.e create mode 100644 library/crypto/eel/tests/test.e create mode 100644 library/crypto/eel/tests/test.e.orig create mode 100644 library/crypto/eel/tests/test_ec_binary.e create mode 100644 library/crypto/eel/tests/test_ec_field_element_f2m.e create mode 100644 library/crypto/eel/tests/tests-safe.ecf create mode 100644 library/crypto/eel/tests/tests.ecf create mode 100644 library/crypto/eel/tests/tests.rc create mode 100644 library/crypto/eel/x509/algorithm_identifier.e create mode 100644 library/crypto/eel/x509/algorithm_parameters.e create mode 100644 library/crypto/eel/x509/attribute_type_and_value.e create mode 100644 library/crypto/eel/x509/certificate.e create mode 100644 library/crypto/eel/x509/extension.e create mode 100644 library/crypto/eel/x509/name.e create mode 100644 library/crypto/eel/x509/object_identifier.e create mode 100644 library/crypto/eel/x509/subject_public_key_info.e create mode 100644 library/crypto/eel/x509/tbs_certificate.e create mode 100644 library/crypto/eel/x509/validity.e diff --git a/.gitmodules b/.gitmodules index 92276b15..ad9fdb20 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,10 +10,3 @@ [submodule "ext/ise_library/curl"] path = ext/ise_library/curl url = http://github.com/EiffelSoftware/mirror-Eiffel-cURL.git -[submodule "ext/crypto/eel"] -[submodule "ext/crypto/eel"] - path = ext/crypto/eel - url = http://github.com/Eiffel-World/eel.git -[submodule "ext/crypto/eapml"] - path = ext/crypto/eapml - url = http://github.com/Eiffel-World/eapml.git diff --git a/examples/restbucks/restbucks-safe.ecf b/examples/restbucks/restbucks-safe.ecf index b04a639f..0be35898 100644 --- a/examples/restbucks/restbucks-safe.ecf +++ b/examples/restbucks/restbucks-safe.ecf @@ -18,7 +18,7 @@ - + diff --git a/ext/crypto/eapml b/ext/crypto/eapml deleted file mode 160000 index 4f341f02..00000000 --- a/ext/crypto/eapml +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4f341f028c1825816bbb7fcb20c6ef11d7843bff diff --git a/ext/crypto/eel b/ext/crypto/eel deleted file mode 160000 index f573b30f..00000000 --- a/ext/crypto/eel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f573b30fec6eece84d36d4210b554d81df34577d diff --git a/library/crypto/eapml/.gitignore b/library/crypto/eapml/.gitignore new file mode 100644 index 00000000..a7f9c034 --- /dev/null +++ b/library/crypto/eapml/.gitignore @@ -0,0 +1 @@ +EIFGENs/ diff --git a/library/crypto/eapml/bit_scan_gcc/limb_bit_scanning.e b/library/crypto/eapml/bit_scan_gcc/limb_bit_scanning.e new file mode 100644 index 00000000..81badefd --- /dev/null +++ b/library/crypto/eapml/bit_scan_gcc/limb_bit_scanning.e @@ -0,0 +1,59 @@ +note + description: "Summary description for {LIMB_BIT_SCANNING}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + LIMB_BIT_SCANNING + +inherit + LIMB_DEFINITION + +feature + + leading_zeros (limb_a: NATURAL_32): INTEGER + do + if limb_a = 0 then + Result := limb_bits + else + Result := count_leading_zeros (limb_a) + end + end + + most_significant_one (limb_a: NATURAL_32): INTEGER + -- 31 high, 0 low + require + limb_a /= 0 + do + Result := limb_high_bit - leading_zeros (limb_a) + end + + trailing_zeros (limb_a: NATURAL_32): INTEGER + -- 31 high, 0 low + require + limb_a /= 0 + do + Result := count_trailing_zeros (limb_a) + end + +feature {NONE} -- Implementation + + count_trailing_zeros (limb_a: NATURAL_32): INTEGER + external + "C inline" + alias + "[ + return __builtin_ctz ($limb_a); + ]" + end + + count_leading_zeros (limb_a: NATURAL_32): INTEGER + external + "C inline" + alias + "[ + return __builtin_clz ($limb_a); + ]" + end +end diff --git a/library/crypto/eapml/bit_scan_vc/limb_bit_scanning.e b/library/crypto/eapml/bit_scan_vc/limb_bit_scanning.e new file mode 100644 index 00000000..e880349c --- /dev/null +++ b/library/crypto/eapml/bit_scan_vc/limb_bit_scanning.e @@ -0,0 +1,59 @@ +note + description: "Summary description for {LIMB_BIT_SCANNING}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + LIMB_BIT_SCANNING + +inherit + LIMB_DEFINITION + +feature + + leading_zeros (limb_a: NATURAL_32): INTEGER + do + if limb_a = 0 then + Result := limb_bits + else + Result := limb_high_bit - most_significant_one (limb_a) + end + end + + most_significant_one (limb_a: NATURAL_32): INTEGER + -- 31 high, 0 low + require + limb_a /= 0 + do + bit_scan_reverse ($Result, limb_a) + end + + trailing_zeros (limb_a: NATURAL_32): INTEGER + -- 31 high, 0 low + require + limb_a /= 0 + do + bit_scan_forward ($Result, limb_a) + end + +feature {NONE} -- Implementation + + bit_scan_reverse (target: POINTER; limb_a: NATURAL_32) + external + "C inline use %"intrin.h%"" + alias + "[ + _BitScanReverse ($target, $limb_a); + ]" + end + + bit_scan_forward (target: POINTER; limb_a: NATURAL_32) + external + "C inline use %"intrin.h%"" + alias + "[ + _BitScanForward ($target, $limb_a); + ]" + end +end diff --git a/library/crypto/eapml/divide_by_zero.e b/library/crypto/eapml/divide_by_zero.e new file mode 100644 index 00000000..de12ac49 --- /dev/null +++ b/library/crypto/eapml/divide_by_zero.e @@ -0,0 +1,19 @@ +note + description: "An exception when dividing by zero" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "A right is not what someone gives you; it's what no one can take from you. - Ramsey Clark, U.S. Attorney General, New York Times, 10/02/77" + +class + DIVIDE_BY_ZERO + +inherit + DEVELOPER_EXCEPTION + redefine + internal_meaning + end + +feature + internal_meaning: STRING = "Divide by zero" +end diff --git a/library/crypto/eapml/eapml-safe.ecf b/library/crypto/eapml/eapml-safe.ecf new file mode 100644 index 00000000..1d0fe889 --- /dev/null +++ b/library/crypto/eapml/eapml-safe.ecf @@ -0,0 +1,50 @@ + + + Eiffel Arbitrary Precision Mathematics Library + + + /.svn$ + /CVS$ + /.hg$ + /EIFGENs$ + + Eiffel Arbitrary Precision Mathematics + + + + + + + + + + + + + + + + /bit_scan_vc$ + /tests$ + /limb_natural_64$ + /bit_scan_gcc$ + /limb_natural_32$ + + + ^/mp/number/support$ + + + + + + + + + + + + + + diff --git a/library/crypto/eapml/eapml.ecf b/library/crypto/eapml/eapml.ecf new file mode 100644 index 00000000..42254f06 --- /dev/null +++ b/library/crypto/eapml/eapml.ecf @@ -0,0 +1,50 @@ + + + Eiffel Arbitrary Precision Mathematics Library + + Eiffel Arbitrary Precision Mathematics + + + /\.svn$ + /\.hg$ + /CVS$ + /EIFGENs$ + + + + + + + + + + + + + + + + /bit_scan_vc$ + /bit_scan_gcc$ + /tests$ + /limb_natural_32$ + /limb_natural_64$ + + + ^/mp/number/support$ + + + + + + + + + + + + + + diff --git a/library/crypto/eapml/facilities/case_insensitive_strategy.e b/library/crypto/eapml/facilities/case_insensitive_strategy.e new file mode 100644 index 00000000..052d26ef --- /dev/null +++ b/library/crypto/eapml/facilities/case_insensitive_strategy.e @@ -0,0 +1,224 @@ +note + description: "Convert between character codes and numbers ignoring case" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "There can be no freedom without freedom to fail. - Eric Hoffer (1902-1983), The Ordeal of Change, 1964" + +class + CASE_INSENSITIVE_STRATEGY + +inherit + CHARACTER_STRATEGY + +feature + + text_to_number (in: NATURAL_8): NATURAL_8 + do + inspect + in + when 0x30 then + Result := 0x0 + when 0x31 then + Result := 1 + when 0x32 then + Result := 2 + when 0x33 then + Result := 3 + when 0x34 then + Result := 4 + when 0x35 then + Result := 5 + when 0x36 then + Result := 6 + when 0x37 then + Result := 7 + when 0x38 then + Result := 8 + when 0x39 then + Result := 9 + when 0x41 then + Result := 10 + when 0x42 then + Result := 11 + when 0x43 then + Result := 12 + when 0x44 then + Result := 13 + when 0x45 then + Result := 14 + when 0x46 then + Result := 15 + when 0x47 then + Result := 16 + when 0x48 then + Result := 17 + when 0x49 then + Result := 18 + when 0x4a then + Result := 19 + when 0x4b then + Result := 20 + when 0x4c then + Result := 21 + when 0x4d then + Result := 22 + when 0x4e then + Result := 23 + when 0x4f then + Result := 24 + when 0x50 then + Result := 25 + when 0x51 then + Result := 26 + when 0x52 then + Result := 27 + when 0x53 then + Result := 28 + when 0x54 then + Result := 29 + when 0x55 then + Result := 30 + when 0x56 then + Result := 31 + when 0x57 then + Result := 32 + when 0x58 then + Result := 33 + when 0x59 then + Result := 34 + when 0x5a then + Result := 35 + when 0x61 then + Result := 10 + when 0x62 then + Result := 11 + when 0x63 then + Result := 12 + when 0x64 then + Result := 13 + when 0x65 then + Result := 14 + when 0x66 then + Result := 15 + when 0x67 then + Result := 16 + when 0x68 then + Result := 17 + when 0x69 then + Result := 18 + when 0x6a then + Result := 19 + when 0x6b then + Result := 20 + when 0x6c then + Result := 21 + when 0x6d then + Result := 22 + when 0x6e then + Result := 23 + when 0x6f then + Result := 24 + when 0x70 then + Result := 25 + when 0x71 then + Result := 26 + when 0x72 then + Result := 27 + when 0x73 then + Result := 28 + when 0x74 then + Result := 29 + when 0x75 then + Result := 30 + when 0x76 then + Result := 31 + when 0x77 then + Result := 32 + when 0x78 then + Result := 33 + when 0x79 then + Result := 34 + when 0x7a then + Result := 35 + end + end + + number_to_text (in: NATURAL_8): NATURAL_8 + do + inspect in + when 0 then + Result := 0x30 + when 1 then + Result := 0x31 + when 2 then + Result := 0x32 + when 3 then + Result := 0x33 + when 4 then + Result := 0x34 + when 5 then + Result := 0x35 + when 6 then + Result := 0x36 + when 7 then + Result := 0x37 + when 8 then + Result := 0x38 + when 9 then + Result := 0x39 + when 10 then + Result := 0x61 + when 11 then + Result := 0x62 + when 12 then + Result := 0x63 + when 13 then + Result := 0x64 + when 14 then + Result := 0x65 + when 15 then + Result := 0x66 + when 16 then + Result := 0x67 + when 17 then + Result := 0x68 + when 18 then + Result := 0x69 + when 19 then + Result := 0x6a + when 20 then + Result := 0x6b + when 21 then + Result := 0x6c + when 22 then + Result := 0x6d + when 23 then + Result := 0x6e + when 24 then + Result := 0x6f + when 25 then + Result := 0x70 + when 26 then + Result := 0x71 + when 27 then + Result := 0x72 + when 28 then + Result := 0x73 + when 29 then + Result := 0x74 + when 30 then + Result := 0x75 + when 31 then + Result := 0x76 + when 32 then + Result := 0x77 + when 33 then + Result := 0x78 + when 34 then + Result := 0x79 + when 35 then + Result := 0x7a + end + end +end diff --git a/library/crypto/eapml/facilities/case_sensitive_strategy.e b/library/crypto/eapml/facilities/case_sensitive_strategy.e new file mode 100644 index 00000000..e1cfb799 --- /dev/null +++ b/library/crypto/eapml/facilities/case_sensitive_strategy.e @@ -0,0 +1,276 @@ +note + description: "Convert between character codes and numbers case-sensitive" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "I believe the State exists for the development of individual lives, not individuals for the development of the state. - Julian Huxley (1878-1975)" + +class + CASE_SENSITIVE_STRATEGY + +inherit + CHARACTER_STRATEGY + +feature + + text_to_number (in: NATURAL_8): NATURAL_8 + do + inspect + in + when 0x30 then + Result := 0x0 + when 0x31 then + Result := 1 + when 0x32 then + Result := 2 + when 0x33 then + Result := 3 + when 0x34 then + Result := 4 + when 0x35 then + Result := 5 + when 0x36 then + Result := 6 + when 0x37 then + Result := 7 + when 0x38 then + Result := 8 + when 0x39 then + Result := 9 + when 0x41 then + Result := 10 + when 0x42 then + Result := 11 + when 0x43 then + Result := 12 + when 0x44 then + Result := 13 + when 0x45 then + Result := 14 + when 0x46 then + Result := 15 + when 0x47 then + Result := 16 + when 0x48 then + Result := 17 + when 0x49 then + Result := 18 + when 0x4a then + Result := 19 + when 0x4b then + Result := 20 + when 0x4c then + Result := 21 + when 0x4d then + Result := 22 + when 0x4e then + Result := 23 + when 0x4f then + Result := 24 + when 0x50 then + Result := 25 + when 0x51 then + Result := 26 + when 0x52 then + Result := 27 + when 0x53 then + Result := 28 + when 0x54 then + Result := 29 + when 0x55 then + Result := 30 + when 0x56 then + Result := 31 + when 0x57 then + Result := 32 + when 0x58 then + Result := 33 + when 0x59 then + Result := 34 + when 0x5a then + Result := 35 + when 0x61 then + Result := 36 + when 0x62 then + Result := 37 + when 0x63 then + Result := 38 + when 0x64 then + Result := 39 + when 0x65 then + Result := 40 + when 0x66 then + Result := 41 + when 0x67 then + Result := 42 + when 0x68 then + Result := 43 + when 0x69 then + Result := 44 + when 0x6a then + Result := 45 + when 0x6b then + Result := 46 + when 0x6c then + Result := 47 + when 0x6d then + Result := 48 + when 0x6e then + Result := 49 + when 0x6f then + Result := 50 + when 0x70 then + Result := 51 + when 0x71 then + Result := 52 + when 0x72 then + Result := 53 + when 0x73 then + Result := 54 + when 0x74 then + Result := 55 + when 0x75 then + Result := 56 + when 0x76 then + Result := 57 + when 0x77 then + Result := 58 + when 0x78 then + Result := 59 + when 0x79 then + Result := 60 + when 0x7a then + Result := 61 + end + end + + number_to_text (in: NATURAL_8): NATURAL_8 + do + inspect in + when 0 then + Result := 0x30 + when 1 then + Result := 0x31 + when 2 then + Result := 0x32 + when 3 then + Result := 0x33 + when 4 then + Result := 0x34 + when 5 then + Result := 0x35 + when 6 then + Result := 0x36 + when 7 then + Result := 0x37 + when 8 then + Result := 0x38 + when 9 then + Result := 0x39 + when 10 then + Result := 0x41 + when 11 then + Result := 0x42 + when 12 then + Result := 0x43 + when 13 then + Result := 0x44 + when 14 then + Result := 0x45 + when 15 then + Result := 0x46 + when 16 then + Result := 0x47 + when 17 then + Result := 0x48 + when 18 then + Result := 0x49 + when 19 then + Result := 0x4a + when 20 then + Result := 0x4b + when 21 then + Result := 0x4c + when 22 then + Result := 0x4d + when 23 then + Result := 0x4e + when 24 then + Result := 0x4f + when 25 then + Result := 0x50 + when 26 then + Result := 0x51 + when 27 then + Result := 0x52 + when 28 then + Result := 0x53 + when 29 then + Result := 0x54 + when 30 then + Result := 0x55 + when 31 then + Result := 0x56 + when 32 then + Result := 0x57 + when 33 then + Result := 0x58 + when 34 then + Result := 0x59 + when 35 then + Result := 0x5a + when 36 then + Result := 0x61 + when 37 then + Result := 0x62 + when 38 then + Result := 0x63 + when 39 then + Result := 0x64 + when 40 then + Result := 0x65 + when 41 then + Result := 0x66 + when 42 then + Result := 0x67 + when 43 then + Result := 0x68 + when 44 then + Result := 0x69 + when 45 then + Result := 0x6a + when 46 then + Result := 0x6b + when 47 then + Result := 0x6c + when 48 then + Result := 0x6d + when 49 then + Result := 0x6e + when 50 then + Result := 0x6f + when 51 then + Result := 0x70 + when 52 then + Result := 0x71 + when 53 then + Result := 0x72 + when 54 then + Result := 0x73 + when 55 then + Result := 0x74 + when 56 then + Result := 0x75 + when 57 then + Result := 0x76 + when 58 then + Result := 0x77 + when 59 then + Result := 0x78 + when 60 then + Result := 0x79 + when 61 then + Result := 0x7a + end + end +end diff --git a/library/crypto/eapml/facilities/character_strategy.e b/library/crypto/eapml/facilities/character_strategy.e new file mode 100644 index 00000000..019f3d7b --- /dev/null +++ b/library/crypto/eapml/facilities/character_strategy.e @@ -0,0 +1,20 @@ +note + description: "A strategy for converting character codes to numbers and vica-versa" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Free speech is meaningless unless it tolerates the speech that we hate. - Henry J. Hyde, U.S. Congressman, Speech, 5/3/91" + +deferred class + CHARACTER_STRATEGY + +feature + + text_to_number (in: NATURAL_8): NATURAL_8 + deferred + end + + number_to_text (in: NATURAL_8): NATURAL_8 + deferred + end +end diff --git a/library/crypto/eapml/facilities/integer_x_access.e b/library/crypto/eapml/facilities/integer_x_access.e new file mode 100644 index 00000000..04ca2f95 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_access.e @@ -0,0 +1,77 @@ +note + description: "Summary description for {INTEGER_X_ACCESS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "It is error alone which needs the support of government. Truth can stand by itself. - Thomas Jefferson (1743-1846), U.S. President, Notes on the State of Virginia, 1782" + +deferred class + INTEGER_X_ACCESS + +inherit + INTEGER_X_FACILITIES + SPECIAL_SIZING + SPECIAL_ACCESS + rename + get_str as get_str_special + end + +feature + + get_string (op: READABLE_INTEGER_X; base: INTEGER): STRING_8 + require + base >= 2 + base <= 62 + local + xp: SPECIAL [NATURAL_32] + xp_offset: INTEGER + x_size: INTEGER + str: STRING_8 + str_offset: INTEGER + return_str: STRING_8 + return_str_offset: INTEGER + str_size: INTEGER + alloc_size: INTEGER + num_to_text: CHARACTER_STRATEGY + i: INTEGER + do + x_size := op.count + if base <= 35 then + create {CASE_INSENSITIVE_STRATEGY}num_to_text + else + create {CASE_SENSITIVE_STRATEGY}num_to_text + end + alloc_size := sizeinbase (op.item, 0, x_size.abs, base) + alloc_size := alloc_size + (x_size < 0).to_integer + create Result.make_filled ('%U', alloc_size) + return_str := Result + return_str_offset := 1 + if x_size < 0 then + return_str [return_str_offset] := '-' + return_str_offset := return_str_offset + 1 + x_size := -x_size + end + xp := op.item + xp_offset := 0 + if not pow2_p (base.to_natural_32) then + create xp.make_filled (0, x_size + 1) + xp.copy_data (op.item, 0, 0, x_size) + end + str_size := get_str_special (return_str, return_str_offset, base, xp, xp_offset, x_size) + str := return_str + str.remove_tail (alloc_size - str_size - (return_str_offset - 1)) + str_offset := return_str_offset + if str [str_offset] = (0x0).to_character_8 and str_size /= 1 then + str_size := str_size - 1 + str_offset := str_offset + 1 + end + from + i := 0 + until + i >= str_size + loop + return_str [return_str_offset + i] := num_to_text.number_to_text (str [str_offset + i].code.to_natural_8).to_character_8 + i := i + 1 + end + end +end diff --git a/library/crypto/eapml/facilities/integer_x_arithmetic.e b/library/crypto/eapml/facilities/integer_x_arithmetic.e new file mode 100644 index 00000000..fb234440 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_arithmetic.e @@ -0,0 +1,914 @@ +note + description: "Summary description for {INTEGER_X_ARITHMETIC}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Every man should know that his conversations, his correspondence, and his personal life are private. - Lyndon B. Johnson (1908-1973), Remarks, 3/10/67" + +deferred class + INTEGER_X_ARITHMETIC + +inherit + INTEGER_X_FACILITIES + SPECIAL_ARITHMETIC + rename + add as add_special, + sub as sub_special, + mul as mul_special + export + {NONE} + all + end + SPECIAL_COMPARISON + SPECIAL_UTILITY + +feature + + add (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X) + -- Set `rop' to `op1' + `op2'. + local + wp: SPECIAL [NATURAL_32] + wp_offset: INTEGER + up: SPECIAL [NATURAL_32] + vp: SPECIAL [NATURAL_32] + usize: INTEGER_32 + vsize: INTEGER_32 + wsize: INTEGER_32 + abs_usize: INTEGER_32 + abs_vsize: INTEGER_32 + pointer_temp: READABLE_INTEGER_X + int_temp: INTEGER_32 + junk2: NATURAL_32 + cy_limb: NATURAL_32 + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + usize := op1.count + vsize := op2.count + abs_usize := usize.abs + abs_vsize := vsize.abs + if abs_usize < abs_vsize then + pointer_temp := op1 + op1 := op2 + op2 := pointer_temp + int_temp := usize + usize := vsize + vsize := int_temp + int_temp := abs_usize + abs_usize := abs_vsize + abs_vsize := int_temp + end + wsize := abs_usize + 1 + target.resize (wsize) + up := op1.item + vp := op2.item + wp := target.item + if usize.bit_xor (vsize) < 0 then + if abs_usize /= abs_vsize then + sub_special (wp, 0, up, 0, abs_usize, vp, 0, abs_vsize, carry) + junk2 := carry.item + wsize := abs_usize + wsize := normalize (wp, wp_offset, wsize) + if usize < 0 then + wsize := -wsize + end + elseif cmp (up, 0, vp, 0, abs_usize) < 0 then + sub_n (wp, 0, vp, 0, up, 0, abs_usize, carry) + junk2 := carry.item + wsize := abs_usize + wsize := normalize (wp, wp_offset, wsize) + if usize >= 0 then + wsize := -wsize + end + else + sub_n (wp, 0, up, 0, vp, 0, abs_usize, carry) + junk2 := carry.item + wsize := abs_usize + wsize := normalize (wp, wp_offset, wsize) + if usize < 0 then + wsize := -wsize + end + end + else + add_special (wp, 0, up, 0, abs_usize, vp, 0, abs_vsize, carry) + cy_limb := carry.item + wp [wp_offset + abs_usize] := cy_limb + wsize := abs_usize + cy_limb.to_integer_32 + if usize < 0 then + wsize := -wsize + end + end + target.count := wsize + end + + add_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL) + -- Set `rop' to `op1' + `op2'. + local + usize: INTEGER_32 + wsize: INTEGER_32 + abs_usize: INTEGER_32 + cy: NATURAL_32 + junk2: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + usize := op1.count + abs_usize := usize.abs + wsize := abs_usize + 1 + target.resize (wsize) + if abs_usize = 0 then + target.item [0] := op2 + if op2 /= 0 then + target.count := 1 + else + target.count := 0 + end + else + if usize >= 0 then + add_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry) + cy := carry.item + target.item [abs_usize] := cy + wsize := abs_usize + cy.to_integer_32 + else + if abs_usize = 1 and op1.item [0] < op2 then + target.item [0] := op2 - op1.item [0] + wsize := 1 + else + sub_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry) + junk2 := carry.item + if target.item [abs_usize - 1] = 0 then + wsize := - (abs_usize - 1) + else + wsize := - (abs_usize) + end + end + end + target.count := wsize + end + end + + aorsmul (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X; sub_a: INTEGER_32) + local + xsize: INTEGER_32 + ysize: INTEGER_32 + tsize: INTEGER_32 + wsize: INTEGER_32 + wsize_signed: INTEGER_32 + wp: INTEGER_32 + tp: SPECIAL [NATURAL_32] + c: NATURAL_32 + high: NATURAL_32 + tmp_marker: SPECIAL [NATURAL_32] + tp_offset: INTEGER_32 + current_temp: READABLE_INTEGER_X + int_temp: INTEGER_32 + usize: INTEGER_32 + sub_l: INTEGER_32 + junk2: NATURAL_32 + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + sub_l := sub_a + xsize := op1.count + ysize := op2.count + if xsize = 0 or ysize = 0 then + else + if ysize.abs > xsize.abs then + current_temp := op1 + op1 := op2 + op2 := current_temp + int_temp := xsize + xsize := ysize + ysize := int_temp + end + sub_l := sub_l.bit_xor (ysize) + ysize := ysize.abs + if ysize = 1 then + aorsmul_1 (target, op1, op2.item [0], sub_l) + else + sub_l := sub_l.bit_xor (xsize) + xsize := xsize.abs + wsize_signed := target.count + sub_l := sub_l.bit_xor (wsize_signed) + wsize := wsize_signed.abs + tsize := xsize + ysize + if wsize > tsize then + if wsize + 1 > target.capacity then + target.resize (wsize) + end + else + if tsize + 1 > target.capacity then + target.resize (tsize) + end + end + if wsize_signed = 0 then + mul_special (target.item, 0, op1.item, 0, xsize, op2.item, 0, ysize, carry) + high := carry.item + if high = 0 then + tsize := tsize - 1 + end + if sub_l >= 0 then + target.count := tsize + else + target.count := -tsize + end + else + create tmp_marker.make_filled (0, tsize) + tp := tmp_marker + tp_offset := 0 + mul_special (tmp_marker, 0, op1.item, 0, xsize, op2.item, 0, ysize, carry) + high := carry.item + if high = 0 then + tsize := tsize - 1 + end + if sub_l >= 0 then + usize := wsize + if usize < tsize then + usize := tsize + tp_offset := wp + tsize := wsize + wsize := usize + end + add_special (target.item, wp, op1.item, 0, usize, tp, 0, tsize, carry) + c := carry.item + target.item [wp + wsize] := c + if c /= 0 then + wsize := wsize + 1 + end + else + usize := wsize + if usize < tsize or usize = tsize and cmp (target.item, wp, tmp_marker, 0, usize) < 0 then + usize := tsize + tp_offset := wp + tsize := wsize + wsize := usize + wsize_signed := -wsize_signed + end + sub_special (target.item, wp, target.item, wp, usize, tp, tp_offset, tsize, carry) + junk2 := carry.item + wsize := usize + from + until + wsize > 0 or target.item [wp + wsize - 1] /= 0 + loop + wsize := wsize - 1 + end + end + if wsize_signed >= 0 then + target.count := wsize + else + target.count := -wsize + end + end + end + end + end + + aorsmul_1 (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL_32; sub_a: INTEGER_32) + local + xsize: INTEGER_32 + wsize: INTEGER_32 + wsize_signed: INTEGER_32 + new_wsize: INTEGER_32 + min_size: INTEGER_32 + dsize: INTEGER_32 + xp: INTEGER_32 + wp: INTEGER_32 + cy: NATURAL_32 + sub_l: INTEGER_32 + cy2: NATURAL_32 + d: INTEGER_32 + s: INTEGER_32 + n: INTEGER_32 + x: NATURAL_32 + p: INTEGER_32 + cy__: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + sub_l := sub_a + xsize := op1.count + if xsize = 0 or op2 = 0 then + else + sub_l := sub_l.bit_xor (xsize) + xsize := xsize.abs + wsize_signed := target.count + if wsize_signed = 0 then + target.resize (xsize + 1) + wp := 0 + mul_1 (target.item, 0, op1.item, 0, xsize, op2, carry) + cy := carry.item + target.item [xsize] := cy + if cy /= 0 then + xsize := xsize + 1 + end + if sub_l >= 0 then + target.count := xsize + else + target.count := -xsize + end + else + sub_l := sub_l.bit_xor (wsize_signed) + wsize := wsize_signed.abs + new_wsize := wsize.max (xsize) + target.resize (new_wsize + 1) + wp := 0 + xp := 0 + min_size := wsize.min (xsize) + if sub_l >= 0 then + addmul_1 (target.item, 0, op1.item, 0, min_size, op2, carry) + cy := carry.item + wp := wp + min_size + xp := xp + min_size + dsize := xsize - wsize + if dsize /= 0 then + if dsize > 0 then + mul_1 (target.item, wp, op1.item, xp, min_size, op2, carry) + cy2 := carry.item + else + dsize := -dsize + cy2 := 0 + end + add_1 (target.item, wp, target.item, wp, dsize, cy, carry) + cy := cy2 + carry.item + end + target.item [wp + dsize] := cy + if cy /= 0 then + new_wsize := new_wsize + 1 + end + else + submul_1 (target.item, wp, op1.item, xp, min_size, op2, carry) + cy := carry.item + if wsize >= xsize then + if wsize /= xsize then + sub_1 (target.item, wp + xsize, op1.item, wp + xsize, wsize - xsize, cy, carry) + cy := carry.item + if cy /= 0 then + target.item [wp + new_wsize] := (-cy.to_integer_32).bit_not.to_natural_32 + d := wp + s := wp + n := new_wsize + from + target.item [d] := target.item [s].bit_not + d := d + 1 + s := s + 1 + n := n - 1 + until + n = 0 + loop + target.item [d] := target.item [s].bit_not + d := d + 1 + s := s + 1 + n := n - 1 + end + new_wsize := new_wsize + 1 + p := wp + x := target.item [p] + 1 + target.item [p] := x + if x < 1 then + from + p := p + 1 + target.item [p] := target.item [p] + 1 + until + target.item [p] /= 0 + loop + p := p + 1 + target.item [p] := target.item [p] + 1 + end + end + wsize_signed := -wsize_signed + end + else + d := wp + s := wp + n := wsize + from + target.item [d] := target.item [s].bit_not + s := s + 1 + d := d + 1 + n := n - 1 + until + n = 0 + loop + target.item [d] := target.item [s].bit_not + s := s + 1 + d := d + 1 + n := n - 1 + end + add_1 (target.item, wp, target.item, wp, wsize, 1, carry) + cy := carry.item + cy := cy - 1 + if cy = (0).to_natural_32.bit_not then + cy2 := cy2 + 1 + end + cy := cy + cy2 + mul_1 (target.item, wp + wsize, target.item, xp + wsize, xsize - wsize, op2, carry) + cy__ := carry.item + add_1 (target.item, wp + wsize, target.item, wp + wsize, xsize - wsize, cy, carry) + cy := cy__ + carry.item + target.item [wp + new_wsize] := cy + if cy /= 0 then + new_wsize := new_wsize + 1 + end + if cy2 /= 0 then + p := wp + wsize + x := target.item [p] + target.item [p] := x - 1 + if x < 1 then + from + p := p + 1 + target.item [p] := target.item [p] - 1 + until + target.item [p] = 0 + loop + p := p + 1 + target.item [p] := target.item [p] - 1 + end + end + end + wsize_signed := -wsize_signed + end + end + from + until + new_wsize <= 0 or target.item [(wp + new_wsize) * 4] /= 0 + loop + new_wsize := new_wsize - 1 + end + end + if wsize_signed >= 0 then + target.count := new_wsize + else + target.count := -new_wsize + end + end + end + end + + sub (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X) + -- Set `rop' to `op1' - `op2'. + local + usize: INTEGER_32 + vsize: INTEGER_32 + wsize: INTEGER_32 + abs_usize: INTEGER_32 + abs_vsize: INTEGER_32 + pointer_temp: READABLE_INTEGER_X + integer_temp: INTEGER_32 + junk2: NATURAL_32 + cy_limb: NATURAL_32 + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + usize := op1.count + vsize := -op2.count + abs_usize := usize.abs + abs_vsize := vsize.abs + if abs_usize < abs_vsize then + pointer_temp := op1 + op1 := op2 + op2 := pointer_temp + integer_temp := usize + usize := vsize + vsize := integer_temp + integer_temp := abs_usize + abs_usize := abs_vsize + abs_vsize := integer_temp + end + wsize := abs_usize + 1 + target.resize (wsize) + if usize.bit_xor (vsize) < 0 then + if abs_usize /= abs_vsize then + sub_special (target.item, 0, op1.item, 0, abs_usize, op2.item, 0, abs_vsize, carry) + junk2 := carry.item + wsize := abs_usize + from + until + wsize <= 0 or target.item [wsize - 1] /= 0 + loop + wsize := wsize - 1 + end + if usize < 0 then + wsize := -wsize + end + elseif cmp (op1.item, 0, op2.item, 0, abs_usize) < 0 then + sub_n (target.item, 0, op2.item, 0, op1.item, 0, abs_usize, carry) + junk2 := carry.item + wsize := abs_usize + from + until + wsize <= 0 or target.item [wsize - 1] /= 0 + loop + wsize := wsize - 1 + end + if usize >= 0 then + wsize := -wsize + end + else + sub_n (target.item, 0, op1.item, 0, op2.item, 0, abs_usize, carry) + junk2 := carry.item + wsize := abs_usize + from + until + wsize <= 0 or target.item [wsize - 1] /= 0 + loop + wsize := wsize - 1 + end + if usize < 0 then + wsize := -wsize + end + end + else + add_special (target.item, 0, op1.item, 0, abs_usize, op2.item, 0, abs_vsize, carry) + cy_limb := carry.item + target.item [abs_usize] := cy_limb + wsize := abs_usize + cy_limb.to_integer_32 + if usize < 0 then + wsize := -wsize + end + end + target.count := wsize + end + + sub_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL) + -- Set `rop' to `op1' - `op2'. + local + usize: INTEGER_32 + wsize: INTEGER_32 + abs_usize: INTEGER_32 + vval: NATURAL_32 + cy: NATURAL_32 + junk2: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + usize := op1.count + abs_usize := usize.abs + wsize := abs_usize + 1 + target.resize (wsize) + if abs_usize = 0 then + target.item [0] := vval + if op2 /= 0 then + target.count := -1 + else + target.count := 0 + end + else + if usize < 0 then + add_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry) + cy := carry.item + target.item [abs_usize] := cy + wsize := - (abs_usize + cy.to_integer_32) + else + if abs_usize = 1 and op1.item [0] < op2 then + target.item [0] := op2 - op1.item [0] + wsize := -1 + else + sub_1 (target.item, 0, op1.item, 0, abs_usize, op2, carry) + junk2 := carry.item + if target.item [abs_usize - 1] = 0 then + wsize := abs_usize - 1 + else + wsize := abs_usize + end + end + end + target.count := wsize + end + end + + ui_sub (target: READABLE_INTEGER_X; op1: NATURAL_32; op2: READABLE_INTEGER_X) + -- Set `rop' to `op1' - `op2'. + local + vn: INTEGER_32 + wn: INTEGER_32 + cy: NATURAL_32 + junk2: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + vn := op2.count + if vn > 1 then + if vn > target.capacity then + target.resize (vn) + end + sub_1 (target.item, 0, op2.item, 0, vn, op1, carry) + junk2 := carry.item + if target.item [vn - 1] = 0 then + wn := - (vn - 1) + else + wn := - vn + end + elseif vn = 1 then + if op1 >= op2.item [0] then + target.item [0] := op1 - op2.item [0] + if target.item [0] /= 0 then + wn := 1 + else + wn := 0 + end + else + target.item [0] := op2.item [0] - op1 + wn := -1 + end + elseif vn = 0 then + target.item [0] := op1 + if op1 /= 0 then + wn := 1 + else + wn := 0 + end + else + vn := -vn + target.resize (vn + 1) + add_1 (target.item, 0, op2.item, 0, vn, op1, carry) + cy := carry.item + target.item [vn] := cy + if cy /= 0 then + wn := vn + 1 + else + wn := vn + end + end + target.count := wn + end + + addmul (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X) + -- Set `rop' to `rop' + `op1' times `op2'. + do + aorsmul (target, op1, op2, 0) + end + + addmul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL) + -- Set `rop' to `rop' + `op1' times `op2'. + do + aorsmul_1 (target, op1, op2, 0) + end + + submul (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X) + -- Set `rop' to `rop' - `op1' times `op2'. + do + aorsmul (target, op1, op2, -1) + end + + submul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL) + -- Set `rop' to `rop' - `op1' times `op2'. + do + aorsmul_1 (target, op1, op2, -1) + end + + mul (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X) + -- Set `rop' to `op1' times `op2'. + local + usize: INTEGER + vsize: INTEGER + wsize: INTEGER + sign_product: INTEGER + vp: SPECIAL [NATURAL_32] + vp_offset: INTEGER + up: SPECIAL [NATURAL_32] + up_offset: INTEGER + wp: SPECIAL [NATURAL_32] + wp_offset: INTEGER + cy_limb: NATURAL_32 + op_temp: READABLE_INTEGER_X + size_temp: INTEGER_32 + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + usize := op1.count + vsize := op2.count + sign_product := usize.bit_xor (vsize) + usize := usize.abs + vsize := vsize.abs + if usize = 0 or vsize = 0 then + target.count := 0 + else + if vsize = 1 then + if usize + 1 > target.capacity then + target.resize (usize + 1) + end + wp := target.item + mul_1 (target.item, 0, op1.item, 0, usize, op2.item [0], carry) + cy_limb := carry.item + target.item [usize] := cy_limb + if cy_limb /= 0 then + usize := usize + 1 + end + if sign_product >= 0 then + target.count := usize + else + target.count := -usize + end + else + wsize := usize + vsize + if wsize <= 32 and target /= op1 and target /= op2 then + target.resize (wsize) + wp := target.item + if usize > vsize then + mul_basecase (wp, 0, op1.item, 0, usize, op2.item, 0, vsize) + else + mul_basecase (wp, 0, op2.item, 0, vsize, op1.item, 0, usize) + end + wsize := wsize - (wp [wp_offset + wsize - 1] = 0).to_integer + if sign_product >= 0 then + target.count := wsize + else + target.count := -wsize + end + else + if usize < vsize then + op_temp := op1 + op1 := op2 + op2 := op_temp + size_temp := usize + usize := vsize + vsize := size_temp + end + up := op1.item + up_offset := 0 + vp := op2.item + vp_offset := 0 + wp := target.item + wp_offset := 0 + if target.capacity < wsize then + create wp.make_filled (0, wsize) + target.item := wp + else + if wp = up then + create up.make_filled (0, usize) + if wp = vp then + vp := up + end + up.copy_data (wp, 0, 0, usize) + elseif wp = vp then + create vp.make_filled (0, vsize) + vp.copy_data (wp, 0, 0, vsize) + end + end + mul_special (wp, 0, up, 0, usize, vp, 0, vsize, carry) + cy_limb := carry.item + wsize := usize + vsize + wsize := wsize - (cy_limb = 0).to_integer + if sign_product < 0 then + target.count := -wsize + else + target.count := wsize + end + end + end + end + end + + mul_2exp (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; count_a: INTEGER) + local + usize: INTEGER + abs_usize: INTEGER + wsize: INTEGER + limb_count: INTEGER + wp: SPECIAL [NATURAL_32] + wp_offset: INTEGER + wlimb: NATURAL_32 + count: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + count := count_a + usize := op1.count + abs_usize := usize.abs + if usize = 0 then + target.count := 0 + else + limb_count := count // limb_bits + wsize := abs_usize + limb_count + 1 + target.resize (wsize) + wp := target.item + wsize := abs_usize + limb_count + count := count \\ limb_bits + if count /= 0 then + lshift (wp, wp_offset + limb_count, op1.item, 0, abs_usize, count, carry) + wlimb := carry.item + if wlimb /= 0 then + wp [wp_offset + wsize] := wlimb + wsize := wsize + 1 + end + else + wp.copy_data (op1.item, 0, wp_offset + limb_count, abs_usize) + end + wp.fill_with (0, wp_offset, wp_offset + limb_count - 1) + if usize >= 0 then + target.count := wsize + else + target.count := -wsize + end + end + end + + mul_si (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: INTEGER) + local + size: INTEGER + sign_product: INTEGER + sml: NATURAL_32 + cy: NATURAL_32 + pp: SPECIAL [NATURAL_32] + pp_offset: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + size := op1.count + sign_product := size + if size = 0 or op2 = 0 then + target.count := 0 + else + size := size.abs + sml := op2.abs.to_natural_32 + target.resize (size + 1) + pp := target.item + mul_1 (pp, pp_offset, op1.item, 0, size, sml, carry) + cy := carry.item + pp [pp_offset + size] := cy + size := size + (cy /= 0).to_integer + end + if sign_product < 0 xor op2 < 0 then + target.count := -size + else + target.count := size + end + end + + mul_ui (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X; op2: NATURAL_32) + local + size: INTEGER + sign_product: INTEGER + sml: NATURAL_32 + cy: NATURAL_32 + pp: SPECIAL [NATURAL_32] + pp_offset: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + size := op1.count + sign_product := size + if size = 0 or op2 = 0 then + target.count := 0 + else + size := size.abs + sml := op2 + target.resize (size + 1) + pp := target.item + mul_1 (pp, pp_offset, op1.item, 0, size, sml, carry) + cy := carry.item + pp [pp_offset + size] := cy + size := size + (cy /= 0).to_integer + end + if sign_product < 0 xor op2 < 0 then + target.count := -size + else + target.count := size + end + end + + neg (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X) + -- Set `rop' to -`op'. + local + usize: INTEGER_32 + size: INTEGER_32 + do + usize := op.count + if target /= op then + size := usize.abs + target.resize (size) + target.item.copy_data (op.item, 0, 0, size) + end + target.count := -usize + end + + abs (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X) + -- Set `rop' to the absolute value of `op'. + local + size: INTEGER_32 + do + size := op.count.abs + if op /= target then + target.resize (size) + target.item.copy_data (op.item, 0, 0, size) + end + target.count := size + end +end diff --git a/library/crypto/eapml/facilities/integer_x_assignment.e b/library/crypto/eapml/facilities/integer_x_assignment.e new file mode 100644 index 00000000..01bb2ec0 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_assignment.e @@ -0,0 +1,155 @@ +note + description: "Summary description for {INTEGER_X_ASSIGNMENT}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The object and practice of liberty lies in the limitation of governmental power. - General Douglas MacArthur" + +deferred class + INTEGER_X_ASSIGNMENT + +inherit + INTEGER_X_FACILITIES + SPECIAL_ASSIGNMENT + rename + set_str as set_str_special + end + MP_BASES + +feature + + swap (target: READABLE_INTEGER_X; other_a: READABLE_INTEGER_X) + -- Swap the values `rop1' and `rop2' efficiently. + local + other_size: INTEGER_32 + other_pointer: SPECIAL [NATURAL_32] + do + other_size := other_a.count + other_pointer := other_a.item + other_a.count := target.count + other_a.item := target.item + target.count := other_size + target.item := other_pointer + end + + set_str (target: READABLE_INTEGER_X; str: READABLE_STRING_8; base_a: INTEGER) + -- Set the value of `rop' from `str', a null-terminated C string in base `base'. + -- White space is allowed in the string, and is simply ignored. + -- The base may vary from 2 to 62, or if base is 0, then the leading characters + -- are used: 0x and 0X for hexadecimal, 0b and 0B for binary, 0 for octal, or + -- decimal otherwise. + -- For bases up to 36, case is ignored; upper-case and lower-case letters have + -- the same value. + -- For bases 37 to 62, upper-case letter represent the usual 10..35 while + -- lower-case letter represent 36..61. + -- This function returns 0 if the entire string is a valid number in base base. + -- Otherwise it returns -1. + require + base_a <= 62 + base_a >= 2 or base_a = 0 + local + base: INTEGER + str_offset: INTEGER + s: SPECIAL [NATURAL_8] + s_offset: INTEGER + begs: INTEGER + i: INTEGER + xsize: INTEGER + c: CHARACTER + negative: BOOLEAN + digit_value: CHARACTER_STRATEGY + str_size: INTEGER + dig: NATURAL_8 + do + base := base_a + if base > 36 then + create {CASE_SENSITIVE_STRATEGY}digit_value + else + create {CASE_INSENSITIVE_STRATEGY}digit_value + end + from + str_offset := 1 + c := ' ' + until + not c.is_space or not str.valid_index (str_offset) + loop + c := str [str_offset] + str_offset := str_offset + 1 + end + if c = '-' then + negative := True + c := str [str_offset] + str_offset := str_offset + 1 + end + if base = 0 then + if digit_value.text_to_number (c.code.to_natural_8) >= 10 then + (create {INTEGER_X_STRING_EXCEPTION}).raise + end + else + if digit_value.text_to_number (c.code.to_natural_8) >= base then + (create {INTEGER_X_STRING_EXCEPTION}).raise + end + end + if base = 0 then + base := 10 + if c = '0' then + base := 8 + if str.valid_index (str_offset) then + c := str [str_offset] + end + str_offset := str_offset + 1 + if c = 'x' or c = 'X' then + base := 16 + c := str [str_offset] + str_offset := str_offset + 1 + elseif c = 'b' or c = 'B' then + base := 2 + c := str [str_offset] + str_offset := str_offset + 1 + end + end + end + from + until + c /= '0' and not c.is_space or not str.valid_index (str_offset) + loop + c := str [str_offset] + str_offset := str_offset + 1 + end + if c.code = 0 then + target.count := 0 + target.item [0] := 0 + else + str_size := str.count - str_offset + 2 + create s.make_filled (0, str_size) + from + i := 0 + until + i >= str_size + loop + if not c.is_space then + dig := digit_value.text_to_number (c.code.to_natural_8) + if dig.to_integer_32 >= base then + (create {INTEGER_X_STRING_EXCEPTION}).raise + end + s [s_offset] := dig + s_offset := s_offset + 1 + end + if str.valid_index (str_offset) then + c := str [str_offset] + end + str_offset := str_offset + 1 + i := i + 1 + end + str_size := s_offset - begs + xsize := (str_size / chars_per_bit_exactly (base)).truncated_to_integer // 32 + 2 + target.resize (xsize) + xsize := set_str_special (target.item, 0, s, begs, str_size, base) + if negative then + target.count := -xsize + else + target.count := xsize + end + end + end +end diff --git a/library/crypto/eapml/facilities/integer_x_comparison.e b/library/crypto/eapml/facilities/integer_x_comparison.e new file mode 100644 index 00000000..b2ca6b96 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_comparison.e @@ -0,0 +1,200 @@ +note + description: "Summary description for {INTEGER_X_COMPARISON}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The marvel of all history is the patience with which men and women submit to burdens unnecessarily laid upon them by their governments. - U.S. Senator William Borah" + +deferred class + INTEGER_X_COMPARISON + +inherit + INTEGER_X_FACILITIES + SPECIAL_COMPARISON + rename + cmp as cmp_special + end + +feature + + compare (op1: READABLE_INTEGER_X; op2: READABLE_INTEGER_X): INTEGER + -- Compare `op1' and `op2'. + -- Return a positive value if `op1' > `op2', zero if `op1' = `op2', or a negative value if `op1' < `op2'. + local + usize: INTEGER_32 + vsize: INTEGER_32 + dsize: INTEGER_32 + asize: INTEGER_32 + cmp_l: INTEGER_32 + do + usize := op1.count + vsize := op2.count + dsize := usize - vsize + if dsize /= 0 then + Result := dsize + else + asize := usize.abs + cmp_l := cmp_special (op1.item, 0, op2.item, 0, asize) + if usize >= 0 then + Result := cmp_l + else + Result := -cmp_l + end + end + end + + cmp_si (op1: READABLE_INTEGER_X; op: INTEGER_32): INTEGER + -- Compare `op1' and `op2'. + -- Return a positive value if `op1' > `op2', zero if `op1' = `op2', or a negative value if `op1' < `op2'. + -- Is a macro and will evaluate their arguments more than once. + local + v_digit: INTEGER_32 + usize: INTEGER_32 + vsize: INTEGER_32 + u_digit: NATURAL_32 + do + v_digit := op + usize := op1.count + vsize := 0 + if v_digit > 0 then + vsize := 1 + elseif v_digit < 0 then + vsize := -1 + v_digit := -v_digit + end + if usize /= vsize then + Result := usize - vsize + else + if usize = 0 then + Result := 0 + else + u_digit := op1.item [0] + if u_digit = v_digit.to_natural_32 then + Result := 0 + else + if u_digit > v_digit.to_natural_32 then + Result := usize + else + Result := -usize + end + end + end + end + end + + cmp_ui (op1: READABLE_INTEGER_X; op: NATURAL): INTEGER + -- Compare `op1' and `op2'. + -- Return a positive value if `op1' > `op2', zero if `op1' = `op2', or a negative value if `op1' < `op2'. + -- Is a macro and will evaluate their arguments more than once. + local + un: INTEGER_32 + ul: NATURAL_32 + v_digit: NATURAL_32 + do + v_digit := op + un := op1.count + if un = 0 then + if v_digit /= 0 then + Result := -1 + else + Result := 0 + end + else + if un = 1 then + ul := op1.item [0] + if ul > v_digit then + Result := 1 + else + if ul < v_digit then + Result := -1 + else + Result := 0 + end + end + else + if un > 0 then + Result := 1 + else + Result := -1 + end + end + end + end + + cmpabs (op1: READABLE_INTEGER_X ;op2: READABLE_INTEGER_X): INTEGER + -- Compare the absolute values of `op1' and `op2'. + -- Return a positive value if abs(`op1') > abs(`op2'), zero if abs(`op1') = abs(`op2'), + -- or a negative value if abs(`op1') < abs(`op2'). + local + usize: INTEGER_32 + vsize: INTEGER_32 + dsize: INTEGER_32 + cmp_l: INTEGER_32 + i: INTEGER_32 + x: NATURAL_32 + y: NATURAL_32 + do + usize := op1.count.abs + vsize := op2.count.abs + dsize := usize - vsize + if dsize /= 0 then + Result := dsize + else + cmp_l := 0 + from + i := usize - 1 + until + i < 0 or cmp_l /= 0 + loop + x := op1.item [i] + y := op2.item [i] + if x /= y then + if x > y then + Result := 1 + else + Result := -1 + end + end + i := i - 1 + variant + i + 2 + end + end + end + + cmpabs_ui (op1: READABLE_INTEGER_X; op: NATURAL_32): INTEGER + -- Compare the absolute values of `op1' and `op2'. + -- Return a positive value if abs(`op1') > abs(`op2'), zero if abs(`op1') = abs(`op2'), + -- or a negative value if abs(`op1') < abs(`op2'). + local + un: INTEGER_32 + ul: NATURAL_32 + v_digit: NATURAL_32 + do + v_digit := op + un := op1.count + if un = 0 then + if v_digit /= 0 then + Result := -1 + else + Result := 0 + end + else + un := un.abs + if un = 1 then + ul := op1.item [0] + if ul > v_digit then + Result := 1 + else + if ul < v_digit then + Result := -1 + else + Result := 0 + end + end + else + Result := 1 + end + end + end +end diff --git a/library/crypto/eapml/facilities/integer_x_division.e b/library/crypto/eapml/facilities/integer_x_division.e new file mode 100644 index 00000000..fda6dfe9 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_division.e @@ -0,0 +1,429 @@ +note + description: "Summary description for {INTEGER_X_DIVISION}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Collecting more taxes than is absolutely necessary is legalized robbery. - President Calvin Coolidge" + +deferred class + INTEGER_X_DIVISION + +inherit + INTEGER_X_FACILITIES + SPECIAL_UTILITY + export + {NONE} + all + end + SPECIAL_DIVISION + rename + add as add_special, + sub as sub_special, + mul as mul_special, + tdiv_qr as tdiv_qr_special + export + {NONE} + all + end + INTEGER_X_ARITHMETIC + INTEGER_X_ASSIGNMENT + rename + add as add_special, + sub as sub_special, + mul as mul_special + export + {NONE} + all + end + +feature + + fdiv_r_2exp (target: READABLE_INTEGER_X; u: READABLE_INTEGER_X; count: INTEGER) + do + cfdiv_r_2exp (target, u, count, -1) + end + + cdiv_r_2exp (target: READABLE_INTEGER_X; u: READABLE_INTEGER_X; count: INTEGER) + do + cfdiv_r_2exp (target, u, count, 1) + end + + cfdiv_r_2exp (target: READABLE_INTEGER_X; u: READABLE_INTEGER_X; count_a: INTEGER; direction: INTEGER) + local + usize: INTEGER + abs_usize: INTEGER + limb_count: INTEGER + i: INTEGER + up: SPECIAL [NATURAL_32] + up_offset: INTEGER + wp: SPECIAL [NATURAL_32] + wp_offset: INTEGER + high: NATURAL_32 + count: INTEGER + returned: BOOLEAN + negate: BOOLEAN + do + create wp.make_empty (0) + count := count_a + usize := u.count + if usize = 0 then + target.count := 0 + else + limb_count := count // 32 + count := count \\ 32 + abs_usize := usize.abs + up := u.item + if usize.bit_xor (direction) < 0 and Current = u and abs_usize <= limb_count then + returned := True + else + if usize.bit_xor (direction) < 0 then + if Current = u then + wp := target.item + else + i := abs_usize.min (limb_count + 1) + target.resize (i) + wp := target.item + wp.copy_data (up, up_offset, wp_offset, i) + if abs_usize <= limb_count then + target.count := usize + returned := True + end + end + else + if abs_usize <= limb_count then + negate := True + else + from + i := 0 + until + i < limb_count or negate + loop + negate := up [up_offset + i] /= 0 + i := i + 1 + end + if not negate then + if up [up_offset + limb_count].bit_and (((1).to_natural_32 |<< count) - 1) /= 0 then + negate := True + else + target.count := 0 + returned := True + end + end + end + if not returned and negate then + target.resize (limb_count + 1) + up := u.item + up_offset := 0 + wp := target.item + wp_offset := 0 + i := abs_usize.min (limb_count + 1) + com_n (wp, wp_offset, up, up_offset, i) + from + until + i > limb_count + loop + wp [wp_offset + i] := high.max_value + i := i + 1 + end + incr_u (wp, wp_offset, 1) + usize := -usize + end + end + end + if not returned then + high := wp [wp_offset + limb_count] + high := high.bit_and (((1).to_natural_32 |<< count) - 1) + wp [wp_offset + limb_count] := high + from + limb_count := limb_count - 1 + until + high /= 0 or limb_count < 0 + loop + high := wp [wp_offset + limb_count] + end + if limb_count < 0 then + target.count := 0 + else + limb_count := limb_count + 1 + if usize >= 0 then + target.count := limb_count + else + target.count := -limb_count + end + end + end + end + end + + mod (target: READABLE_INTEGER_X; dividend: READABLE_INTEGER_X; divisor_a: READABLE_INTEGER_X) + local + divisor_size: INTEGER + temp_divisor: INTEGER_X + divisor: READABLE_INTEGER_X + do + divisor := divisor_a + divisor_size := divisor.count + if target = divisor then + create temp_divisor.make_limbs (divisor_size.abs) + temp_divisor.set_from_other (divisor) + divisor := temp_divisor + end + tdiv_r (target, dividend, divisor) + if target.count /= 0 then + if dividend.count < 0 then + if divisor.count < 0 then + sub (target, target, divisor) + else + add (target, target, divisor) + end + end + end + end + + tdiv_q (target: READABLE_INTEGER_X; numerator: READABLE_INTEGER_X; denominator: READABLE_INTEGER_X) + local + ql: INTEGER + ns: INTEGER + ds: INTEGER + nl: INTEGER + dl: INTEGER + np: SPECIAL [NATURAL_32] + np_offset: INTEGER + dp: SPECIAL [NATURAL_32] + dp_offset: INTEGER + qp: SPECIAL [NATURAL_32] + qp_offset: INTEGER + rp: SPECIAL [NATURAL_32] + rp_offset: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + do + ns := numerator.count + ds := denominator.count + nl := ns.abs + dl := ds.abs + ql := nl - dl + 1 + + if dl = 0 then + (create {DIVIDE_BY_ZERO}).raise + end + if ql <= 0 then + target.count := 0 + else + target.resize (ql) + qp := target.item + create rp.make_filled (0, dl) + np := numerator.item + dp := denominator.item + if dp = qp then + create tp.make_filled (0, dl) + tp.copy_data (dp, dp_offset, tp_offset, dl) + dp := tp + end + if np = qp then + create tp.make_filled (0, nl) + tp.copy_data (np, np_offset, tp_offset, nl) + np := tp + end + tdiv_qr_special (qp, qp_offset, rp, rp_offset, np, np_offset, nl, dp, dp_offset, dl) + ql := ql - (qp [qp_offset + ql - 1] = 0).to_integer + if ns.bit_xor (ds) >= 0 then + target.count := ql + else + target.count := -ql + end + end + end + + tdiv_q_2exp (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X; count_a: INTEGER_32) + local + usize: INTEGER + wsize: INTEGER + limb_count: INTEGER + wp: SPECIAL [NATURAL_32] + wp_offset: INTEGER + up: SPECIAL [NATURAL_32] + up_offset: INTEGER + junk: NATURAL_32 + count: INTEGER_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + count := count_a + usize := op.count + limb_count := count // 32 + wsize := usize.abs - limb_count + if wsize <= 0 then + target.count := 0 + else + target.resize (wsize) + wp := target.item + up := op.item + count := count \\ 32 + if count /= 0 then + rshift (wp, wp_offset, up, up_offset + limb_count, wsize, count, carry) + junk := carry.item + wsize := wsize - (wp [wp_offset + wsize - 1] = 0).to_integer + else + wp.copy_data (up, up_offset + limb_count, wp_offset, wsize) + end + if usize >= 0 then + target.count := wsize + else + target.count := -wsize + end + end + end + + tdiv_qr (target: READABLE_INTEGER_X; remainder: READABLE_INTEGER_X; numerator: READABLE_INTEGER_X; denominator: READABLE_INTEGER_X) + local + ql: INTEGER_32 + ns: INTEGER_32 + ds: INTEGER_32 + nl: INTEGER_32 + dl: INTEGER_32 + temp_dp: SPECIAL [NATURAL_32] + temp_np: SPECIAL [NATURAL_32] + do + ns := numerator.count + ds := denominator.count + nl := ns.abs + dl := ds.abs + ql := nl - dl + 1 + if dl = 0 then + (create {DIVIDE_BY_ZERO}).raise + end + remainder.resize (dl) + if ql <= 0 then + if numerator /= remainder then + remainder.item.copy_data (numerator.item, 0, 0, nl) + remainder.count := numerator.count + end + target.count := 0 + else + target.resize (ql) + if denominator = remainder or denominator = Current then + create temp_dp.make_empty (dl) + temp_dp.copy_data (denominator.item, 0, 0, dl) + else + temp_dp := denominator.item + end + if numerator = remainder or numerator = Current then + create temp_np.make_empty (nl) + temp_np.copy_data (numerator.item, 0, 0, nl) + else + temp_np := numerator.item + end + tdiv_qr_special (target.item, 0, remainder.item, 0, temp_np, 0, nl, temp_dp, 0, dl) + if target.item [ql - 1] = 0 then + ql := ql - 1 + end + remainder.count := normalize (remainder.item, 0, remainder.count) + dl := remainder.count + if ns.bit_xor (ds) >= 0 then + target.count := ql + else + target.count := -ql + end + if ns >= 0 then + remainder.count := dl + else + remainder.count := -dl + end + end + end + + tdiv_r (remainder: READABLE_INTEGER_X; numerator: READABLE_INTEGER_X; denominator: READABLE_INTEGER_X) + local + ql: INTEGER + ns: INTEGER + ds: INTEGER + nl: INTEGER + dl: INTEGER + np: SPECIAL [NATURAL_32] + np_offset: INTEGER + dp: SPECIAL [NATURAL_32] + dp_offset: INTEGER + qp: SPECIAL [NATURAL_32] + qp_offset: INTEGER + rp: SPECIAL [NATURAL_32] + rp_offset: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + do + ns := numerator.count + ds := denominator.count + nl := ns.abs + dl := ds.abs + ql := nl - dl + 1 + if dl = 0 then + (create {DIVIDE_BY_ZERO}).raise + end + remainder.resize (dl) + if ql <= 0 then + if numerator /= remainder then + np := numerator.item + rp := remainder.item + rp.copy_data (np, 0, 0, nl) + remainder.count := numerator.count + end + else + create qp.make_filled (0, ql) + rp := remainder.item + np := numerator.item + dp := denominator.item + if dp = rp then + create tp.make_filled (0, nl) + tp.copy_data (np, np_offset, tp_offset, nl) + np := tp + np_offset := tp_offset + end + tdiv_qr_special (qp, qp_offset, rp, rp_offset, np, np_offset, nl, dp, dp_offset, dl) + dl := normalize (rp, rp_offset, dl) + if ns >= 0 then + remainder.count := dl + else + remainder.count := -dl + end + end + end + + tdiv_r_2exp (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X; count: INTEGER) + local + in_size: INTEGER + res_size: INTEGER + limb_count: INTEGER + in_ptr: SPECIAL [NATURAL_32] + in_ptr_offset: INTEGER + x: NATURAL_32 + do + in_size := op.count.abs + limb_count := count // 32 + in_ptr := op.item + if in_size > limb_count then + x := in_ptr [in_ptr_offset + limb_count].bit_and (((1).to_natural_32 |<< (count \\ 32)- 1)) + if x /= 0 then + res_size := limb_count + 1 + target.resize (res_size) + target.item [limb_count] := x + else + res_size := limb_count + res_size := normalize (in_ptr, in_ptr_offset, res_size) + target.resize (res_size) + limb_count := res_size + end + else + res_size := in_size + target.resize (res_size) + limb_count := res_size + end + if target /= op then + target.item.copy_data (op.item, 0, 0, limb_count) + end + if op.count >= 0 then + target.count := res_size + else + target.count := -res_size + end + end +end diff --git a/library/crypto/eapml/facilities/integer_x_facilities.e b/library/crypto/eapml/facilities/integer_x_facilities.e new file mode 100644 index 00000000..d1eccae3 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_facilities.e @@ -0,0 +1,11 @@ +note + description: "Summary description for {INTEGER_X_FACILITIES}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Concentrated power is not rendered harmless by the good intentions of those who create it. - Milton Friedman, Nobel prize-winning economist" + +deferred class + INTEGER_X_FACILITIES + +end diff --git a/library/crypto/eapml/facilities/integer_x_gcd.e b/library/crypto/eapml/facilities/integer_x_gcd.e new file mode 100644 index 00000000..e3b21d5d --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_gcd.e @@ -0,0 +1,145 @@ +note + description: "Summary description for {INTEGER_X_GCD}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "'Need' now means wanting someone else's money. 'Greed' means wanting to keep your own. 'Compassion' is when a politician arranges the transfer. - Joseph Sobran, columnist." + +deferred class + INTEGER_X_GCD + +inherit + INTEGER_X_FACILITIES + SPECIAL_GCD + rename + gcd as gcd_special + export + {NONE} + all + end + +feature + + gcd (g: READABLE_INTEGER_X; u: READABLE_INTEGER_X; v: READABLE_INTEGER_X) + local + g_zero_bits: INTEGER + u_zero_bits: INTEGER + v_zero_bits: INTEGER + g_zero_limbs: INTEGER + u_zero_limbs: INTEGER + v_zero_limbs: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + up: SPECIAL [NATURAL_32] + up_offset: INTEGER + usize: INTEGER + vp: SPECIAL [NATURAL_32] + vp_offset: INTEGER + vsize: INTEGER + gsize: INTEGER + junk: NATURAL_32 + cy_limb: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + up := u.item + usize := u.count.abs + vp := v.item + vsize := v.count.abs + if usize = 0 then + g.count := vsize + if g = v then + else + g.resize (vsize) + g.item.copy_data (vp, 0, 0, vsize) + end + elseif vsize = 0 then + g.count := usize + if g = u then + else + g.resize (usize) + g.item.copy_data (up, up_offset, 0, usize) + end + elseif usize = 1 then + g.count := 1 + g.item [0] := gcd_1 (vp, vp_offset, vsize, up [up_offset]) + elseif vsize = 1 then + g.count := 1 + g.item [0] := gcd_1 (up, up_offset, usize, vp [vp_offset]) + else + from + until + up [up_offset] /= 0 + loop + up_offset := up_offset + 1 + end + u_zero_limbs := up_offset - 0 + usize := usize - u_zero_limbs + u_zero_bits := trailing_zeros (up [up_offset]) + tp := up + tp_offset := up_offset + create up.make_filled (0, usize) + if u_zero_bits /= 0 then + rshift (up, up_offset, tp, tp_offset, usize, u_zero_bits, carry) + junk := carry.item + usize := usize - (up [up_offset + usize - 1] = 0).to_integer + else + up.copy_data (tp, tp_offset, up_offset, usize) + end + from + until + vp [vp_offset] /= 0 + loop + vp_offset := vp_offset + 1 + end + v_zero_limbs := vp_offset - 0 + vsize := vsize - v_zero_limbs + v_zero_bits := trailing_zeros (vp [vp_offset]) + tp := vp + tp_offset := vp_offset + create vp.make_filled (0, vsize) + if v_zero_bits /= 0 then + rshift (vp, vp_offset, tp, tp_offset, vsize, v_zero_bits, carry) + junk := carry.item + vsize := vsize - (vp [vp_offset + vsize - 1] = 0).to_integer + else + vp.copy_data (tp, tp_offset, vp_offset, vsize) + end + if u_zero_limbs > v_zero_limbs then + g_zero_limbs := v_zero_limbs + g_zero_bits := v_zero_bits + elseif u_zero_limbs < v_zero_limbs then + g_zero_limbs := u_zero_limbs + g_zero_bits := u_zero_bits + else + g_zero_limbs := u_zero_limbs + g_zero_bits := u_zero_bits.min (v_zero_bits) + end + if usize < vsize or (usize = vsize and up [up_offset + usize - 1] < vp [vp_offset + vsize - 1]) then + vsize := gcd_special (vp, vp_offset, vp, vp_offset, vsize, up, up_offset, usize) + else + vsize := gcd_special (vp, vp_offset, up, up_offset, usize, vp, vp_offset, vsize) + end + gsize := vsize + g_zero_limbs + if g_zero_bits /= 0 then + gsize := gsize + ((vp [vp_offset + vsize - 1] |>> (32 - g_zero_bits)) /= 0).to_integer + g.resize (gsize) + g.item.fill_with (0, 0, g_zero_limbs) + tp := g.item + tp_offset := g_zero_limbs + lshift (tp, tp_offset, vp, vp_offset, vsize, g_zero_bits, carry) + cy_limb := carry.item + if cy_limb /= 0 then + tp [tp_offset + vsize] := cy_limb + end + else + g.resize (gsize) + g.item.fill_with (0, 0, g_zero_limbs) + g.item.copy_data (vp, vp_offset, g_zero_limbs, vsize) + end + g.count := gsize + end + ensure + g.count /= 0 + end +end diff --git a/library/crypto/eapml/facilities/integer_x_io.e b/library/crypto/eapml/facilities/integer_x_io.e new file mode 100644 index 00000000..d8d110e6 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_io.e @@ -0,0 +1,335 @@ +note + description: "Summary description for {INTEGER_X_IO}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "I personally call the type of government which can be removed without violence 'democracy,' and the other, 'tyranny.' - Karl Popper" + +deferred class + INTEGER_X_IO + +inherit + INTEGER_X_FACILITIES + SPECIAL_SIZING + SPECIAL_UTILITY + LIMB_MANIPULATION + +feature + + output (target: SPECIAL [NATURAL_8]; target_offset: INTEGER; countp: TUPLE [countp: INTEGER]; order: INTEGER; size: INTEGER; endian_a: INTEGER; z: READABLE_INTEGER_X) + local + zsize: INTEGER + zp: SPECIAL [NATURAL_32] + zp_offset: INTEGER + count: INTEGER + numb: INTEGER + endian: INTEGER + i: INTEGER + j: INTEGER + limb: NATURAL_32 + wbitsmask: NATURAL_32 + wbytes: INTEGER + woffset: INTEGER + dp: SPECIAL [NATURAL_8] + dp_offset: INTEGER + lbits: INTEGER + wbits: INTEGER + zend: INTEGER + newlimb: NATURAL_32 + done: BOOLEAN + do + endian := endian_a + zsize := z.count + if zsize = 0 then + countp.countp := 0 + else + zsize := zsize.abs + zp := z.item + numb := 8 * size + count := sizeinbase_2exp (zp, zp_offset, zsize, numb) + countp.countp := count + if endian = 0 then + endian := -1 + end + if size = 4 then + if order = -1 and endian = -1 then + from + i := target_offset + j := zp_offset + until + j >= zp_offset + count - 1 + loop + write_limb (zp [zp_offset + j], target, target_offset + i) + i := i + 4 + j := j + 1 + end + done := True + elseif order = 1 and endian = -1 then + from + i := target_offset + j := zp_offset + count - 1 + until + j < zp_offset + loop + write_limb (zp [zp_offset + j], target, target_offset + i) + j := j - 1 + i := i + 4 + end + done := True + elseif order = -1 and endian = 1 then + from + i := target_offset + j := zp_offset + until + j >= zp_offset + count - 1 + loop + write_limb_be (zp [zp_offset + j], target, target_offset + i) + j := j + 1 + i := i + 4 + end + done := True + elseif order = 1 and endian = 1 then + from + i := target_offset + j := zp_offset + count - 1 + until + j < zp_offset + loop + write_limb_be (zp [zp_offset + j], target, target_offset + i) + j := j - 1 + i := i + 4 + end + done := True + end + end + if not done then + numb := size * 8 + wbytes := numb // 8 + wbits := numb \\ 8 + wbitsmask := ((1).to_natural_8 |<< wbits) - 1 + if endian >= 0 then + woffset := size + else + woffset := -size + end + if order < 0 then + woffset := woffset + size + else + woffset := woffset + -size + end + dp := target + dp_offset := target_offset + if order >= 0 then + dp_offset := dp_offset + (count - 1) * size + else + dp_offset := dp_offset + 0 + end + if endian >= 0 then + dp_offset := dp_offset + size - 1 + else + dp_offset := dp_offset + 0 + end + zend := zp_offset + zsize + lbits := 0 + limb := 0 + from + i := 0 + until + i >= count + loop + from + j := 0 + until + j >= wbytes + loop + if lbits >= 8 then + dp [dp_offset] := limb.to_natural_8 + limb := limb |>> 8 + lbits := lbits - 8 + else + if zp_offset = zend then + newlimb := 0 + else + newlimb := zp [zp_offset] + zp_offset := zp_offset + 1 + end + dp [dp_offset] := (limb.bit_or (newlimb |<< lbits)).to_natural_8 + limb := newlimb |>> (8 - lbits) + lbits := lbits + limb_bits - 8 + end + dp_offset := dp_offset - endian + j := j + 1 + end + if wbits /= 0 then + if lbits >= wbits then + dp [dp_offset] := limb.bit_and (wbitsmask).to_natural_8 + limb := limb |>> wbits + lbits := lbits - wbits + else + if zp_offset = zend then + newlimb := 0 + else + newlimb := zp [zp_offset] + zp_offset := zp_offset + 1 + end + dp [dp_offset] := (limb.bit_or (newlimb |<< lbits)).bit_and (wbitsmask).to_natural_8 + limb := newlimb |>> (wbits - lbits) + lbits := lbits + limb_bits - wbits + end + end + from + until + j >= size + loop + dp [dp_offset] := 0 + dp_offset := dp_offset - endian + j := j + 1 + end + dp_offset := dp_offset + woffset + i := i + 1 + end + end + end + end + + input (z: READABLE_INTEGER_X; count: INTEGER; order: INTEGER; size: INTEGER; endian_a: INTEGER; source: SPECIAL [NATURAL_8]; source_offset: INTEGER) + local + zsize: INTEGER + zp: SPECIAL [NATURAL_32] + zp_offset: INTEGER + i: INTEGER + j: INTEGER + done: BOOLEAN + limb: NATURAL_32 + byte: NATURAL_32 + wbitsmask: NATURAL_8 + numb: INTEGER + wbytes: INTEGER + woffset: INTEGER + dp: SPECIAL [NATURAL_8] + dp_offset: INTEGER + lbits: INTEGER + wbits: INTEGER + endian: INTEGER + do + endian := endian_a + zsize := (count * (8 * size) + limb_bits - 1) // limb_bits + z.resize (zsize) + zp := z.item + if endian = 0 then + endian := -1 + end + if order = -1 and size = 4 and endian = -1 then + from + i := zp_offset + j := source_offset + until + i >= count + zp_offset - 1 + loop + zp [zp_offset + i] := read_limb (source, source_offset + j) + j := j + 4 + i := i + 1 + end + done := True + elseif order = -1 and size = 4 and endian = 1 then + from + i := zp_offset + j := source_offset + until + i >= count + zp_offset - 1 + loop + zp [zp_offset + i] := read_limb_be (source, source_offset + j) + j := j + 4 + i := i + 1 + end + done := True + elseif order = 1 and size = 4 and endian = -1 then + from + i := zp_offset + count - 1 + j := source_offset + until + i < zp_offset + loop + zp [zp_offset + i] := read_limb (source, source_offset + j) + j := j + 4 + i := i - 1 + end + done := True + end + if not done then + numb := size * 8 + wbytes := numb // 8 + wbits := numb \\ 8 + wbitsmask := ((1).to_natural_8 |<< wbits) - 1 + woffset := (numb + 7) // 8 + if endian >= 0 then + woffset := woffset + else + woffset := -woffset + end + if order < 0 then + woffset := woffset + size + else + woffset := woffset + -size + end + dp := source + dp_offset := source_offset + if order >= 0 then + dp_offset := dp_offset + (count - 1) * size + else + dp_offset := dp_offset + 0 + end + if endian >= 0 then + dp_offset := dp_offset + size - 1 + else + dp_offset := dp_offset + 0 + end + limb := 0 + lbits := 0 + from + i := 0 + until + i >= count + loop + from + j := 0 + until + j >= wbytes + loop + byte := dp [dp_offset] + dp_offset := dp_offset - endian + limb := limb.bit_or (byte |<< lbits) + lbits := lbits + 8 + if lbits >= limb_bits then + zp [zp_offset] := limb + zp_offset := zp_offset + 1 + lbits := lbits - limb_bits + limb := byte |>> (8 - lbits) + end + j := j + 1 + end + if wbits /= 0 then + byte := dp [dp_offset].bit_and (wbitsmask) + dp_offset := dp_offset - endian + limb := limb.bit_or (byte |<< lbits) + lbits := lbits + wbits + if lbits >= limb_bits then + zp [zp_offset] := limb + zp_offset := zp_offset + 1 + lbits := lbits - limb_bits + limb := byte |>> (wbits - lbits) + end + end + dp_offset := dp_offset + woffset + i := i + 1 + end + if lbits /= 0 then + zp [zp_offset] := limb + zp_offset := zp_offset + 1 + end + end + zp := z.item + zsize := normalize (zp, 0, zsize) + z.count := zsize + end +end diff --git a/library/crypto/eapml/facilities/integer_x_logic.e b/library/crypto/eapml/facilities/integer_x_logic.e new file mode 100644 index 00000000..a275932c --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_logic.e @@ -0,0 +1,1037 @@ +note + description: "Summary description for {INTEGER_X_LOGIC}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The politicians don't just want your money. They want your soul. They want you to be worn down by taxes until you are dependent and helpless. - James Dale Davidson, National Taxpayers Union" + +deferred class + INTEGER_X_LOGIC + +inherit + INTEGER_X_FACILITIES + SPECIAL_ARITHMETIC + rename + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + SPECIAL_UTILITY + +feature + + bit_and (target: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X) + local + op1_ptr: SPECIAL [NATURAL_32] + op1_ptr_offset: INTEGER + op2_ptr: SPECIAL [NATURAL_32] + op2_ptr_offset: INTEGER + op1_size: INTEGER + op2_size: INTEGER + res_ptr: SPECIAL [NATURAL_32] + res_ptr_offset: INTEGER + res_size: INTEGER + i: INTEGER + junk: NATURAL_32 + done: BOOLEAN + opx: SPECIAL [NATURAL_32] + opx_offset: INTEGER + cy: NATURAL_32 + res_alloc: INTEGER + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + tmp_integer_x: READABLE_INTEGER_X + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + op1_size := op1.count + op2_size := op2.count + op1_ptr := op1.item + op2_ptr := op2.item + res_ptr := target.item + if op1_size >= 0 then + if op2_size >= 0 then + res_size := op1_size.min (op2_size) + from + i := res_size - 1 + until + i < 0 or else op1_ptr [op1_ptr_offset + i].bit_and (op2_ptr [op2_ptr_offset + i]) /= 0 + loop + i := i - 1 + end + res_size := i + 1 + target.resize (res_size) + res_ptr := target.item + op1_ptr := op1.item + op2_ptr := op2.item + target.count := res_size + if res_size /= 0 then + add_n (res_ptr, res_ptr_offset, op1_ptr, op1_ptr_offset, op2_ptr, op2_ptr_offset, res_size, carry) + junk := carry.item + end + done := True + end + else + if op2_size < 0 then + op1_size := -op1_size + op2_size := -op2_size + res_alloc := 1 + op1_size.max (op2_size) + create opx.make_filled (0, op1_size) + sub_1 (opx, opx_offset, op1_ptr, op1_ptr_offset, op1_size, 1, carry) + junk := carry.item + op1_ptr := opx + create opx.make_filled (0, op2_size) + sub_1 (opx, opx_offset, op2_ptr, op2_ptr_offset, op2_size, 1, carry) + junk := carry.item + op2_ptr := opx + target.resize (res_alloc) + res_ptr := target.item + if op1_size >= op2_size then + res_ptr.copy_data (op1_ptr, op1_ptr_offset + op2_size, res_ptr_offset + op2_size, op1_size - op2_size) + from + i := op2_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_or (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op1_size + else + res_ptr.copy_data (op2_ptr, op2_ptr_offset + op1_size, res_ptr_offset + op1_size, op2_size - op1_size) + from + i := op1_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_or (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op2_size + end + add_1 (res_ptr, res_ptr_offset, res_ptr, res_ptr_offset, res_size, 1, carry) + cy := carry.item + if cy /= 0 then + res_ptr [res_ptr_offset + res_size] := cy + res_size := res_size + 1 + end + target.count := -res_size + done := True + else + tmp_integer_x := op1 + op1 := op2 + op2 := tmp_integer_x + tmp_special := op1_ptr + op1_ptr := op2_ptr + op2_ptr := tmp_special + tmp_integer := op1_ptr_offset + op1_ptr_offset := op2_ptr_offset + op2_ptr_offset := tmp_integer + end + end + if not done then + op2_size := -op2_size + create opx.make_filled (0, op2_size) + sub_1 (opx, opx_offset, op2_ptr, op2_ptr_offset, op2_size, 1, carry) + junk := carry.item + op2_ptr := opx + if op1_size > op2_size then + res_size := op1_size + target.resize (res_size) + res_ptr := target.item + op1_ptr := op1.item + res_ptr.copy_data (op1_ptr, op1_ptr_offset + op2_size, res_ptr_offset + op2_size, res_size - op2_size) + from + i := op2_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_and (op2_ptr [op2_ptr_offset + i].bit_not) + i := i - 1 + end + target.count := res_size + else + from + i := op1_size - 1 + until + i < 0 or else op1_ptr [op1_ptr_offset + i].bit_and (op2_ptr [op2_ptr_offset + i].bit_not) /= 0 + loop + i := i - 1 + end + res_size := i + 1 + target.resize (res_size) + res_ptr := target.item + op1_ptr := op1.item + from + i := res_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_and (op2_ptr [op2_ptr_offset + i].bit_not) + i := i - 1 + end + target.count := res_size + end + end + end + + bit_clear (op: READABLE_INTEGER_X; bit_index: INTEGER_32) + -- Clear bit `bit_index' in `rop'. + local + dsize: INTEGER_32 + dp: SPECIAL [NATURAL_32] + dp_offset: INTEGER + limb_index: INTEGER + dlimb: NATURAL_32 + zero_bound: INTEGER + i: INTEGER_32 + done: BOOLEAN + do + dsize := op.count + dp := op.item + limb_index := bit_index // limb_bits + if dsize >= 0 then + if limb_index < dsize then + dlimb := dp [dp_offset + limb_index] + dlimb := dlimb.bit_and (((1) |<< (bit_index \\ limb_bits)).bit_not.to_natural_32) + dp [dp_offset + limb_index] := dlimb + if dlimb = 0 and limb_index = dsize - 1 then + from + dsize := dsize - 1 + until + dsize <= 0 or dp [dp_offset + dsize - 1] /= 0 + loop + dsize := dsize - 1 + end + op.count := dsize + end + end + else + dsize := -dsize + from + zero_bound := 0 + until + dp [dp_offset + zero_bound] /= 0 + loop + zero_bound := zero_bound + 1 + end + if limb_index > zero_bound then + if limb_index < dsize then + dp [dp_offset + limb_index] := dp [dp_offset + limb_index].bit_or (((1) |<< (bit_index \\ limb_bits)).to_natural_32) + else + op.resize (limb_index + 1) + dp := op.item + dp.fill_with (0, dp_offset + dsize, dp_offset + dsize + (limb_index - dsize) - 1) + dp [dp_offset + limb_index] := ((1) |<< (bit_index \\ (limb_bits))).to_natural_32 + op.count := - (limb_index + 1) + end + elseif limb_index = zero_bound then + dp [dp_offset + limb_index] := (dp [dp_offset + limb_index] - 1).bit_or (((1) |<< (bit_index \\ limb_bits)).to_natural_32) + if dp [dp_offset + limb_index] = 0 then + from + i := limb_index + 1 + until + i >= dsize or done + loop + dp [dp_offset + 1] := dp [dp_offset + 1] + 1 + if dp [dp_offset + i] = 0 then + done := True + else + i := i + 1 + end + end + if not done then + dsize := dsize + 1 + op.resize (dsize) + dp [dp_offset + i] := 1 + op.count := -dsize + end + end + end + end + end + + bit_one_complement (target: READABLE_INTEGER_X; op: READABLE_INTEGER_X) + -- Set `rop' to the one's complement of `op'. + local + src: READABLE_INTEGER_X + size: INTEGER_32 + cy: NATURAL_32 + junk2: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + src := op + size := src.count + if size >= 0 then + target.resize (size + 1) + if size = 0 then + target.item [0] := 1 + target.count := -1 + else + add_1 (target.item, 0, src.item, 0, size, 1, carry) + cy := carry.item + if cy /= 0 then + target.item [size] := cy + size := size + 1 + end + target.count := -size + end + else + size := -size + target.resize (size) + sub_1 (target.item, 0, src.item, 0, size, 1, carry) + junk2 := carry.item + if target.item [size - 1] = 0 then + size := size - 1 + end + target.count := size + end + end + + bit_complement (d: READABLE_INTEGER_X; bit_index: INTEGER_32) + local + dsize: INTEGER + dp: SPECIAL [NATURAL_32] + limb_index: INTEGER + bit_l: NATURAL_32 + x: NATURAL_32 + i: INTEGER + c: NATURAL_32 + junk: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + dsize := d.count.abs + dp := d.item + limb_index := bit_index // limb_bits + bit_l := (1).to_natural_32 |<< (bit_index \\ limb_bits) + if limb_index >= dsize then + d.resize (limb_index + 1) + dp := d.item + dsize := limb_index + 1 + end + if d.count >= 0 then + dp [limb_index] := dp [limb_index].bit_xor (bit_l) + dsize := normalize (dp, 0, dsize) + d.count := dsize + else + x := 0 - dp [limb_index] + from + i := limb_index - 1 + until + i < 0 + loop + if dp [i] /= 0 then + x := x - 1 + i := 0 + end + i := i - 1 + end + if x.bit_and (bit_l) /= 0 then + d.resize (dsize + 1) + dp := d.item + add_1 (dp, limb_index, dp, limb_index, dsize - limb_index, bit_l, carry) + c := carry.item + dp [dsize] := c + dsize := dsize + c.to_integer_32 + else + sub_1 (dp, limb_index, dp, limb_index, dsize + limb_index, bit_l, carry) + junk := carry.item + dsize := normalize (dp, 0, dsize) + d.count := -dsize + end + end + end + + bit_or (res: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X; op2_a: READABLE_INTEGER_X) + local + op1_ptr: SPECIAL [NATURAL_32] + op1_ptr_offset: INTEGER + op2_ptr: SPECIAL [NATURAL_32] + op2_ptr_offset: INTEGER + op1_size: INTEGER + op2_size: INTEGER + res_ptr: SPECIAL [NATURAL_32] + res_ptr_offset: INTEGER + res_size: INTEGER + i: INTEGER + done: BOOLEAN + opx: SPECIAL [NATURAL_32] + opx_offset: INTEGER + cy: NATURAL_32 + junk: NATURAL_32 + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + tmp_integer_x: READABLE_INTEGER_X + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + res_alloc: INTEGER + count: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + op1_size := op1.count + op2_size := op2.count + op1_ptr := op1.item + op2_ptr := op2.item + res_ptr := res.item + if op1_size >= 0 then + if op2_size >= 0 then + if op1_size >= op2_size then + res.resize (op1_size) + op1_ptr := op1.item + op2_ptr := op2.item + res_ptr := res.item + if res_ptr /= op1_ptr then + res_ptr.copy_data (op1_ptr, op1_ptr_offset + op2_size, res_ptr_offset + op2_size, op1_size - op2_size) + end + from + i := op2_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_or (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op1_size + else + res.resize (op2_size) + op1_ptr := op1.item + op2_ptr := op2.item + res_ptr := res.item + if res_ptr /= op2_ptr then + res_ptr.copy_data (op2_ptr, op2_ptr_offset + op1_size, res_ptr_offset + op1_size, op2_size - op1_size) + end + from + i := op1_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_or (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + end + res_size := op2_size + done := True + end + else + if op2_size < 0 then + op1_size := -op1_size + op2_size := -op2_size + res_size := op1_size.min (op2_size) + create opx.make_filled (0, res_size) + sub_1 (opx, opx_offset, op1_ptr, op1_ptr_offset, res_size, 1, carry) + junk := carry.item + op1_ptr := opx + create opx.make_filled (0, res_size) + sub_1 (opx, opx_offset, op2_ptr, op2_ptr_offset, res_size, 1, carry) + junk := carry.item + op2_ptr := opx + res.resize (res_size) + res_ptr := res.item + from + i := res_size - 1 + until + i < 0 or else op1_ptr [op1_ptr_offset + i].bit_and (op2_ptr [op2_ptr_offset + i]) /= 0 + loop + i := i - 1 + end + res_size := i + 1 + if res_size /= 0 then + from + i := res_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_and (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + add_1 (res_ptr, res_ptr_offset, res_ptr, res_ptr_offset, res_size, 1, carry) + cy := carry.item + if cy /= 0 then + res_ptr [res_ptr_offset + res_size] := cy + res_size := res_size + 1 + end + else + res_ptr [res_ptr_offset] := 1 + res_size := 1 + end + res.count := -res_size + done := True + else + tmp_integer_x := op1 + op1 := op2 + op2 := tmp_integer_x + tmp_special := op1_ptr + op1_ptr := op2_ptr + op2_ptr := tmp_special + tmp_integer := op1_ptr_offset + op1_ptr_offset := op2_ptr_offset + op2_ptr_offset := tmp_integer + end + end + if not done then + op2_size := -op2_size + res_alloc := op2_size + create opx.make_filled (0, op2_size) + sub_1 (opx, opx_offset, op2_ptr, op2_ptr_offset, op2_size, 1, carry) + junk := carry.item + op2_ptr := opx + op2_size := op2_size - (op2_ptr [op2_ptr_offset + op2_size - 1] = 0).to_integer + res.resize (res_alloc) + op1_ptr := op1.item + res_ptr := res.item + if op1_size >= op2_size then + from + i := op2_size - 1 + until + i < 0 or else op1_ptr [op1_ptr_offset + i].bit_not.bit_and (op2_ptr [op2_ptr_offset + i]) /= 0 + loop + i := i - 1 + end + res_size := i + 1 + count := res_size + else + res_size := op2_size + res_ptr.copy_data (op2_ptr, op2_ptr_offset + op1_size, res_ptr_offset + op1_size, op2_size - op1_size) + count := op1_size + end + if res_size /= 0 then + from + i := count - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_not.bit_and (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + add_1 (res_ptr, res_ptr_offset, res_ptr, res_ptr_offset, res_size, 1, carry) + cy := carry.item + if cy /= 0 then + res_ptr [res_ptr_offset + res_size] := cy + res_size := res_size + 1 + else + res_ptr [res_ptr_offset] := 1 + res_size := 1 + end + res.count := -res_size + end + end + end + + bit_scan_0 (op: READABLE_INTEGER_X; starting_bit: INTEGER_32): INTEGER + -- Scan `op', starting from bit `starting_bit', towards more significant bits, until the first 0 + -- bit is found. + -- Return the index of the found bit. + -- The least significant bit is number 0. + -- If the bit at `starting_bit' is already what's sought, then `starting_bit' is returned. + -- If there's no bit found, then ULONG_MAX is returned. + -- This will happen past the end of a negative number. + local + u_ptr: INTEGER_32 + size: INTEGER_32 + abs_size: INTEGER_32 + u_end: INTEGER_32 + starting_limb: INTEGER_32 + p: INTEGER_32 + limb: NATURAL_32 + cnt: INTEGER_32 + done: BOOLEAN + q: INTEGER_32 + do + size := op.count + abs_size := size.abs + u_end := abs_size + starting_limb := starting_bit // (4 |<< 3) + p := starting_limb + if starting_limb >= abs_size then + if size >= 0 then + Result := starting_bit + else + Result := Result.max_value + end + else + limb := op.item [p] + if size >= 0 then + limb := limb.bit_or (((1) |<< (starting_bit \\ (4 |<< 3))).to_natural_32) + from + until + limb /= (0).to_natural_32.bit_not or done + loop + p := p + 1 + if p = u_end then + done := true + Result := (abs_size * 4 |<< 3) + else + limb := op.item [p] + end + end + if not done then + limb := limb.bit_not + end + else + q := p + from + until + q = u_ptr or done + loop + q := q - 1 + if op.item [q] /= 0 then + done := true + end + end + if not done then + limb := limb - 1 + end + limb := limb.bit_and (((0).to_natural_32.bit_not |<< (starting_bit \\ (4 |<< 3)))) + if limb = 0 then + p := p + 1 + if p = u_end then + Result := Result.max_value + else + from + limb := op.item [p] + until + limb /= 0 + loop + p := p + 1 + end + end + end + end + cnt := trailing_zeros (op.item [limb.to_integer_32]) + Result := p - u_ptr + cnt + end + end + + bit_scan_1 (op1: READABLE_INTEGER_X; starting_bit: INTEGER): INTEGER + local + u_ptr: SPECIAL [NATURAL_32] + u_ptr_offset: INTEGER + size: INTEGER + abs_size: INTEGER + u_end: INTEGER + starting_limb: INTEGER + p: INTEGER + limb: NATURAL_32 + count: INTEGER + q: INTEGER + inverted: NATURAL_32 + got_limb: BOOLEAN + do + u_ptr := op1.item + size := op1.count + abs_size := size.abs + u_end := u_ptr_offset + abs_size + starting_limb := starting_bit // limb_bits + p := u_ptr_offset + starting_limb + if starting_limb >= abs_size then + if size >= 0 then + Result := Result.max_value + else + Result := starting_bit + end + end + limb := u_ptr [p] + if size >= 0 and limb.bit_and (limb.max_value |<< (starting_bit \\ limb_bits)) = 0 and p + 1 = u_end then + Result := Result.max_value + else + if size >= 0 then + limb := limb.bit_and (limb.max_value |<< (starting_bit \\ limb_bits)) + if limb = 0 then + p := p + 1 + from + limb := u_ptr [p] + p := p + 1 + until + limb /= 0 + loop + limb := u_ptr [p] + p := p + 1 + end + end + else + q := p + from + inverted := 0 + until + q = u_ptr_offset or inverted /= 0 + loop + q := q - 1 + inverted := u_ptr [q] + end + if inverted = 0 then + if limb = 0 then + from + limb := 1 + until + limb = 0 + loop + p := p + 1 + limb := u_ptr [p] + end + limb := 0 - limb + got_limb := True + else + limb := limb - 1 + end + end + if not got_limb then + limb := limb.bit_or ((1).to_natural_32 |<< (starting_bit \\ limb_bits) - 1) + from + limb := 0 + p := p + 1 + if p /= u_end then + limb := u_ptr [p] + end + until + p = u_end or limb = limb.max_value + loop + p := p + 1 + if p /= u_end then + limb := u_ptr [p] + end + end + if p = u_end then + Result := abs_size * limb_bits + else + limb := limb.bit_not + count := trailing_zeros (limb) + Result := (p - u_ptr_offset) * limb_bits + count + end + else + count := trailing_zeros (limb) + Result := (p - u_ptr_offset) * limb_bits + count + end + end + end + end + + bit_set (op: READABLE_INTEGER_X; bit_index: INTEGER_32) + -- Set bit `bit_index' in `rop'. + local + dsize: INTEGER_32 + dp: INTEGER_32 + limb_index: INTEGER_32 + dst: INTEGER_32 + n: INTEGER_32 + zero_bound: INTEGER_32 + dlimb: NATURAL_32 + i: INTEGER_32 + done: BOOLEAN + x: NATURAL_32 + p: INTEGER_32 + last_p: NATURAL_32 + do + dsize := op.count + dp := 0 + limb_index := bit_index // limb_bits + if dsize >= 0 then + if limb_index < dsize then + op.item [dp + limb_index] := op.item [dp + limb_index].bit_or ((1).to_natural_32 |<< (bit_index \\ limb_bits)) + op.count := dsize + else + op.resize (limb_index + 1) + if limb_index - dsize /= 0 then + dst := dp + dsize + n := limb_index - dsize + from + op.item [dst] := 0 + dst := dst + 1 + n := n - 1 + until + n = 0 + loop + op.item [dst] := 0 + dst := dst + 1 + n := n - 1 + end + end + op.item [dp + limb_index] := ((1) |<< (bit_index \\ limb_bits)).to_natural_32 + op.count := limb_index + 1 + end + else + dsize := -dsize + from + zero_bound := 0 + until + op.item [dp + zero_bound] /= 0 + loop + zero_bound := zero_bound + 1 + end + if limb_index > zero_bound then + if limb_index < dsize then + dlimb := op.item [dp + limb_index] + dlimb := dlimb.bit_and (((1) |<< (bit_index \\ limb_bits)).bit_not.to_natural_32) + op.item [dp + limb_index] := dlimb + if dlimb = 0 and limb_index = dsize - 1 then + from + dsize := dsize - 1 + until + dsize <= 0 or op.item [dp + dsize - 1] /= 0 + loop + dsize := dsize - 1 + end + op.count := -dsize + end + end + elseif limb_index = zero_bound then + op.item [dp + limb_index] := (op.item [dp + limb_index] - 1).bit_and (((1).to_natural_32 |<< (bit_index \\ limb_bits)).bit_not) - 1 + if op.item [dp + limb_index] = 0 then + from + i := limb_index + 1 + until + i >= dsize or done + loop + op.item [dp + i] := op.item [dp + i] + 1 + if op.item [dp + i] /= 0 then + done := true + else + i := i + 1 + end + end + if not done then + dsize := dsize + 1 + op.resize (dsize) + op.item [dp + i] := 1 + op.count := -dsize + end + end + else + p := dp + limb_index + x := op.item [p] + op.item [p] := x - ((1) |<< (bit_index \\ limb_bits)).to_natural_32 + if x < ((1) |<< (bit_index \\ limb_bits)).to_natural_32 then + from + p := p + 1 + last_p := op.item [p] + op.item [p] := last_p - 1 + until + last_p = 0 + loop + p := p + 1 + last_p := op.item [p] + op.item [p] := last_p - 1 + end + end + if op.item [dp + dsize - 1] = 0 then + dsize := dsize - 1 + end + op.count := -dsize + end + end + end + + bit_test (op: READABLE_INTEGER_X; bit_index: INTEGER): BOOLEAN + local + u_ptr: SPECIAL [NATURAL_32] + size: INTEGER + abs_size: INTEGER + limb_index: INTEGER + p_offset: INTEGER + limb: NATURAL_32 + do + u_ptr := op.item + size := op.count + abs_size := size.abs + limb_index := bit_index // limb_bits + p_offset := 0 + limb_index + if limb_index >= abs_size then + Result := size < 0 + else + limb := u_ptr [p_offset] + if size < 0 then + limb := 0 - limb + from + until + p_offset = 0 + loop + p_offset := p_offset - 1 + if u_ptr [p_offset] /= 0 then + limb := limb - 1 + p_offset := 0 + end + end + end + Result := limb.bit_test (bit_index \\ limb_bits) + end + end + + bit_xor (res: READABLE_INTEGER_X; op1_a: READABLE_INTEGER_X op2_a: READABLE_INTEGER_X) + local + op1_ptr: SPECIAL [NATURAL_32] + op1_ptr_offset: INTEGER + op2_ptr: SPECIAL [NATURAL_32] + op2_ptr_offset: INTEGER + op1_size: INTEGER + op2_size: INTEGER + res_ptr: SPECIAL [NATURAL_32] + res_ptr_offset: INTEGER + res_size: INTEGER + res_alloc: INTEGER + i: INTEGER + opx: SPECIAL [NATURAL_32] + opx_offset: INTEGER + junk: NATURAL_32 + done: BOOLEAN + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + tmp_integer_x: READABLE_INTEGER_X + op1: READABLE_INTEGER_X + op2: READABLE_INTEGER_X + cy: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + op1 := op1_a + op2 := op2_a + op1_size := op1.count + op2_size := op2.count + op1_ptr := op1.item + op2_ptr := op2.item + res_ptr := res.item + if op1_size >= 0 then + if op2_size >= 0 then + res_size := op1_size.max (op2_size) + res.resize (res_size) + res_ptr := res.item + op1_ptr := op1.item + op2_ptr := op2.item + bit_xor_special (res_ptr, 0, op1_ptr, 0, op1_size, op2_ptr, 0, op2_size) + res_size := normalize (res_ptr, res_ptr_offset, res_size) + res.count := res_size + done := True + end + else + if op2_size < 0 then + op1_size := -op1_size + op2_size := -op2_size + create opx.make_filled (0, op1_size) + sub_1 (opx, opx_offset, op1_ptr, op1_ptr_offset, op1_size, 1, carry) + junk := carry.item + op1_ptr := opx + op1_ptr_offset := opx_offset + create opx.make_filled (0, op2_size) + sub_1 (opx, opx_offset, op2_ptr, op2_ptr_offset, op2_size, 1, carry) + junk := carry.item + op2_ptr := opx + op2_ptr_offset := opx_offset + res_alloc := op1_size.max (op2_size) + res.resize (res_alloc) + res_ptr := res.item + if op1_size > op2_size then + res_ptr.copy_data (op1_ptr, op1_ptr_offset + op2_size, res_ptr_offset + op2_size, op1_size - op2_size) + from + i := op2_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_xor (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op1_size + else + res_ptr.copy_data (op2_ptr, op2_ptr_offset + op1_size, res_ptr_offset + op1_size, op2_size - op1_size) + from + i := op1_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_xor (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op2_size + end + res_size := normalize (res_ptr, res_ptr_offset, res_size) + res.count := res_size + done := True + else + tmp_integer_x := op1 + op1 := op2 + op2 := tmp_integer_x + tmp_special := op1_ptr + op1_ptr := op2_ptr + op2_ptr := tmp_special + tmp_integer := op1_ptr_offset + op1_ptr_offset := op2_ptr_offset + op2_ptr_offset := tmp_integer + tmp_integer := op1_size + op1_size := op2_size + op2_size := tmp_integer + end + end + if not done then + op2_size := -op2_size + create opx.make_filled (0, op2_size) + sub_1 (opx, opx_offset, op2_ptr, op2_ptr_offset, op2_size, 1, carry) + junk := carry.item + op2_ptr := opx + op2_ptr_offset := opx_offset + res_alloc := op1_size.max (op2_size) + 1 + res.resize (res_alloc) + res_ptr := res.item + if op1_size > op2_size then + res_ptr.copy_data (op1_ptr, op1_ptr_offset + op2_size, res_ptr_offset + op2_size, op1_size - op2_size) + from + i := op2_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_xor (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op1_size + else + res_ptr.copy_data (op2_ptr, op2_ptr_offset + op1_size, res_ptr_offset + op1_size, op2_size - op1_size) + from + i := op1_size - 1 + until + i < 0 + loop + res_ptr [res_ptr_offset + i] := op1_ptr [op1_ptr_offset + i].bit_xor (op2_ptr [op2_ptr_offset + i]) + i := i - 1 + end + res_size := op2_size + end + add_1 (res_ptr, res_ptr_offset, res_ptr, res_ptr_offset, res_size, 1, carry) + cy := carry.item + if cy /= 0 then + res_ptr [res_ptr_offset + res_size] := cy + res_size := res_size + 1 + end + res_size := normalize (res_ptr, res_ptr_offset, res_size) + res.count := - res_size + end + end + + bit_xor_lshift (target: READABLE_INTEGER_X; op1: READABLE_INTEGER_X op2_a: READABLE_INTEGER_X left_shift_bits: INTEGER) + -- Bit XOR `op1' with (`op2' left shifted `left_shift_bits' bits) + local + op2: READABLE_INTEGER_X + target_special: SPECIAL [NATURAL_32] + op1_special: SPECIAL [NATURAL_32] + op1_count: INTEGER + op2_count: INTEGER + target_count_max: INTEGER + do + if target = op2_a or op1 = op2_a then + op2 := op2_a.identity + else + op2 := op2_a + end + op1_special := op1.item + op1_count := op1.count + op2_count := op2.count + target_count_max := op1_count + op2_count + bits_to_limbs (left_shift_bits) + target.resize (target_count_max) + target_special := target.item + bit_xor_lshift_special (target_special, 0, op1_special, 0, op1_count, op2.item, 0, op2_count, left_shift_bits) + target.count := normalize (target_special, 0, target_count_max) + end +end diff --git a/library/crypto/eapml/facilities/integer_x_number_theory.e b/library/crypto/eapml/facilities/integer_x_number_theory.e new file mode 100644 index 00000000..8d88f45b --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_number_theory.e @@ -0,0 +1,967 @@ +note + description: "Summary description for {INTEGER_X_NUMBER_THEORY}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Gun registration is a gateway drug. - Mark Gilmore" + +deferred class + INTEGER_X_NUMBER_THEORY + +inherit + INTEGER_X_FACILITIES + SPECIAL_ARITHMETIC + rename + add as add_special, + sub as sub_special, + mul as mul_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + end + SPECIAL_DIVISION + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + tdiv_qr as tdiv_qr_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + end + SPECIAL_NUMBER_THEORETIC + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + tdiv_qr as tdiv_qr_special, + gcdext as gcdext_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special, + invert_gf as invert_gf_special + export + {NONE} + all + end + INTEGER_X_ACCESS + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + tdiv_qr as tdiv_qr_special, + sizeinbase as sizeinbase_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_ARITHMETIC + rename + cmp as cmp_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_ASSIGNMENT + rename + add as add_special, + sub as sub_special, + mul as mul_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_COMPARISON + INTEGER_X_LOGIC + rename + add as add_special, + sub as sub_special, + mul as mul_special + end + INTEGER_X_DIVISION + rename + cmp as cmp_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_RANDOM + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_GCD + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + tdiv_qr as tdiv_qr_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_SIZING + +feature + + millerrabin_test (n: READABLE_INTEGER_X; nm1: READABLE_INTEGER_X; x: READABLE_INTEGER_X; y: READABLE_INTEGER_X; q: READABLE_INTEGER_X; k: INTEGER): INTEGER + local + i: INTEGER + do + powm (y, x, q, n) + if cmp_ui (y, 1) = 0 or compare (y, nm1) = 0 then + Result := 1 + else + from + i := 1 + Result := -1 + until + Result /= -1 or i >= k + loop + powm_ui (y, y, 2, n) + if compare (y, nm1) = 0 then + Result := 1 + elseif cmp_ui (y, 1) = 0 then + Result := 0 + end + i := i + 1 + end + if Result = -1 then + Result := 0 + end + end + end + + bin_uiui (target: READABLE_INTEGER_X; n_a: NATURAL_32; k_a: NATURAL_32) + -- Compute the binomial coefficient `n' over `k' and store the result in `rop'. + local + i: NATURAL_32 + j: NATURAL_32 + cnt: NATURAL_32 + n1: CELL [NATURAL_32] + n0: CELL [NATURAL_32] + k0: NATURAL_32 +-- t: NATURAL_64 + k: NATURAL_32 + n: NATURAL_32 + rsize: CELL [INTEGER] + ralloc: CELL [INTEGER] + nacc: CELL [NATURAL_32] + kacc: CELL [NATURAL_32] + do + create n0.put (0) + create n1.put (0) + create rsize.put (0) + create ralloc.put (0) + create nacc.put (0) + create kacc.put (0) + n := n_a + k := k_a + if n < k then + target.count := 0 + else + k := k.min (n - k) + if k = 0 then + target.count := 1 + target.item [0] := 1 + else + j := n - k + 1 + target.item [0] := j + target.count := 1 + ralloc.put (target.capacity) + nacc.put (1) + kacc.put (1) + cnt := 0 + from + i := 2 + until + i > k + loop + j := j + 1 + cnt := nacc.item.bit_or (kacc.item).bit_and (1).bit_xor (1) + nacc.put (nacc.item |>> cnt.to_integer_32) + kacc.put (kacc.item |>> cnt.to_integer_32) + umul_ppmm (n1, n0, nacc.item, j) + k0 := kacc.item * i + if n1.item /= 0 then + muldiv (target, 32, rsize, ralloc, nacc, kacc) + nacc.put (j) + kacc.put (i) + else + nacc.put (n0.item) + kacc.put (k0) + end + i := i + 1 + end + muldiv (target, 1, rsize, ralloc, nacc, kacc) + target.count := rsize.item + end + end + end + + gcdext (g: READABLE_INTEGER_X; s: detachable READABLE_INTEGER_X; t: detachable READABLE_INTEGER_X; a: READABLE_INTEGER_X; b: READABLE_INTEGER_X) + -- Set `g' to the greatest common divisor of `a' and `b', and in addition set `s' and `t' to + -- coefficients satisfying `a*s + b*t = g'. + -- `g' is always positive, even if one or both of `a' and `b' are negative. + -- If `t' is NULL then that value is not computed. + local + asize: INTEGER + bsize: INTEGER + usize: INTEGER + vsize: INTEGER + ap: SPECIAL [NATURAL_32] + ap_offset: INTEGER + bp: SPECIAL [NATURAL_32] + bp_offset: INTEGER + up: SPECIAL [NATURAL_32] + up_offset: INTEGER + vp: SPECIAL [NATURAL_32] + vp_offset: INTEGER + gsize: INTEGER + ssize: INTEGER + tmp_ssize: TUPLE [tmp_ssize: INTEGER] + gp: SPECIAL [NATURAL_32] + sp: SPECIAL [NATURAL_32] + tmp_gp: SPECIAL [NATURAL_32] + tmp_gp_offset: INTEGER + tmp_sp: SPECIAL [NATURAL_32] + tmp_sp_offset: INTEGER + u: READABLE_INTEGER_X + v: READABLE_INTEGER_X + ss: detachable READABLE_INTEGER_X + tt: detachable READABLE_INTEGER_X + gtmp: INTEGER_X + stmp: INTEGER_X + x: INTEGER_X + do + create tmp_ssize + asize := a.count.abs + bsize := b.count.abs + ap := a.item + bp := b.item + if asize > bsize or (asize = bsize and cmp_special (ap, ap_offset, bp, bp_offset, asize) > 0) then + usize := asize + vsize := bsize + create up.make_filled (0, usize + 1) + create vp.make_filled (0, vsize + 1) + up.copy_data (ap, ap_offset, up_offset, usize) + vp.copy_data (bp, bp_offset, vp_offset, vsize) + u := a + v := b + ss := s + tt := t + else + usize := bsize + vsize := asize + create up.make_filled (0, usize + 1) + create vp.make_filled (0, vsize + 1) + up.copy_data (bp, bp_offset, up_offset, usize) + vp.copy_data (ap, ap_offset, vp_offset, vsize) + u := b + v := a + ss := t + tt := s + end + create tmp_gp.make_filled (0, usize + 1) + create tmp_sp.make_filled (0, usize + 1) + if vsize = 0 then + tmp_sp [tmp_sp_offset] := 1 + tmp_ssize.tmp_ssize := 1 + tmp_gp.copy_data (up, up_offset, tmp_gp_offset, usize) + gsize := usize + else + gsize := gcdext_special (tmp_gp, tmp_gp_offset, tmp_sp, tmp_sp_offset, tmp_ssize, up, up_offset, usize, vp, vp_offset, vsize) + end + ssize := tmp_ssize.tmp_ssize.abs + create gtmp + gtmp.item := tmp_gp + gtmp.count := gsize + create stmp + stmp.item := tmp_sp + if tmp_ssize.tmp_ssize.bit_xor (u.count) >= 0 then + stmp.count := ssize + else + stmp.count := -ssize + end + if attached {READABLE_INTEGER_X} tt as tt_l then + if v.count = 0 then + tt_l.count := 0 + else + create x.make_limbs (ssize + usize + 1) + mul (x, stmp, u) + sub (x, gtmp, x) + tdiv_q (tt_l, x, v) + end + end + if attached {READABLE_INTEGER_X} ss as ss_l then + ss_l.resize (ssize) + sp := ss_l.item + sp.copy_data (tmp_sp, tmp_sp_offset, 0, ssize) + ss_l.count := stmp.count + end + g.resize (gsize) + gp := g.item + gp.copy_data (tmp_gp, tmp_gp_offset, 0, gsize) + g.count := gsize + end + + invert (target: READABLE_INTEGER_X; x: READABLE_INTEGER_X; n: READABLE_INTEGER_X): BOOLEAN + local + gcd_l: INTEGER_X + tmp: INTEGER_X + xsize: INTEGER_32 + nsize: INTEGER_32 + size: INTEGER_32 + do + xsize := x.count.abs + nsize := n.count.abs + size := xsize.max (nsize) + 1 + if xsize = 0 or (nsize = 1 and n.item [0] = 1) then + Result := False + else + create gcd_l.make_limbs (size) + create tmp.make_limbs (size) + gcdext (gcd_l, tmp, void, x, n) + if gcd_l.count /= 1 or gcd_l.item [0] /= 1 then + Result := False + else + if tmp.count < 0 then + if n.count < 0 then + sub (target, tmp, n) + else + add (target, tmp, n) + end + else + target.copy (tmp) + end + Result := True + end + end + end + + millerrabin (source: READABLE_INTEGER_X; reps: INTEGER): INTEGER + local + r: INTEGER + nm1: INTEGER_X + nm3: INTEGER_X + x: INTEGER_X + y: INTEGER_X + q: INTEGER_X + k: INTEGER + is_prime: INTEGER + rstate: MERSENNE_TWISTER_RNG + do + create nm1.make_limbs (source.count + 1) + sub_ui (nm1, source, 1) + create x.make_limbs (source.count + 1) + create y.make_limbs (2 * source.count) + x.set_from_natural_32 (210) + powm (y, x, nm1, source) + if cmp_ui (y, 1) /= 0 then + Result := 0 + else + create q.make_limbs (source.count) + k := bit_scan_1 (nm1, 0) + tdiv_q_2exp (q, nm1, k) + create nm3.make_limbs (source.count + 1) + sub_ui (nm3, source, 3) + create rstate.make + is_prime := 1 + from + r := 0 + until + r >= reps or is_prime = 0 + loop + urandomm (x, rstate, nm3) + add_ui (x, x, 2) + is_prime := millerrabin_test (source, nm1, x, y, q, k) + r := r + 1 + end + Result := is_prime + end + end + + powm (r: READABLE_INTEGER_X; b_a: READABLE_INTEGER_X; e: READABLE_INTEGER_X; m: READABLE_INTEGER_X) + local + xp: SPECIAL [NATURAL_32] + xp_offset: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + qp: SPECIAL [NATURAL_32] + qp_offset: INTEGER + gp: SPECIAL [NATURAL_32] + gp_offset: INTEGER + this_gp: SPECIAL [NATURAL_32] + this_gp_offset: INTEGER + bp: SPECIAL [NATURAL_32] + bp_offset: INTEGER + ep: SPECIAL [NATURAL_32] + ep_offset: INTEGER + mp: SPECIAL [NATURAL_32] + mp_offset: INTEGER + bn: INTEGER + es: INTEGER + en: INTEGER + mn: INTEGER + xn: INTEGER + invm: NATURAL_32 + c: NATURAL_32 + enb: INTEGER + i: INTEGER + big_k: INTEGER + j: INTEGER + l: INTEGER + small_k: INTEGER + m_zero_cnt: INTEGER + e_zero_cnt: INTEGER + sh: INTEGER + use_redc: BOOLEAN + new_b: INTEGER_X + b: READABLE_INTEGER_X + new_mp: SPECIAL [NATURAL_32] + new_mp_offset: INTEGER + junk: NATURAL_32 + cy: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + b := b_a + mp := m.item + mn := m.count.abs + if mn = 0 then + (create {DIVIDE_BY_ZERO}).raise + end + es := e.count + if es = 0 then + if mn = 1 and mp [mp_offset] = 1 then + r.count := 0 + else + r.count := 1 + end + r.item [0] := 1 + else + if es < 0 then + create new_b.make_limbs (mn + 1) + if not invert (new_b, b, m) then + (create {INVERSE_EXCEPTION}).raise + end + b := new_b + es := -es + end + en := es + use_redc := (mn < 170) and (mp [mp_offset] \\ 2 /= 0) + if use_redc then + invm := modlimb_invert (mp [mp_offset]) + invm := 0 - invm + else + m_zero_cnt := leading_zeros (mp [mp_offset + mn - 1]) + if m_zero_cnt /= 0 then + create new_mp.make_filled (0, mn) + lshift (new_mp, new_mp_offset, mp, mp_offset, mn, m_zero_cnt, carry) + junk := carry.item + mp := new_mp + mp_offset := new_mp_offset + end + end + e_zero_cnt := leading_zeros (e.item [en - 1]) + enb := en * limb_bits - e_zero_cnt + small_k := 1 + big_k := 2 + from + until + small_k = 10 or 2 * enb <= big_k * (2 + small_k * (3 + small_k)) + loop + small_k := small_k + 1 + big_k := big_k * 2 + end + create tp.make_filled (0, 2 * mn) + create qp.make_filled (0, mn + 1) + create gp.make_filled (0, big_k // 2 * mn) + bn := b.count.abs + bp := b.item + if bn > mn or (bn = mn and cmp_special (bp, bp_offset, mp, mp_offset, mn) >= 0) then + if use_redc then + reduce (tp, tp_offset + mn, bp, bp_offset, bn, mp, mp_offset, mn) + tp.fill_with (0, tp_offset, mn - tp_offset - 1) + tdiv_qr_special (qp, qp_offset, gp, gp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + else + reduce (gp, gp_offset, bp, bp_offset, bn, mp, mp_offset, mn) + end + else + if use_redc then + tp.copy_data (bp, bp_offset, tp_offset + mn, bn) + tdiv_qr_special (qp, qp_offset, gp, gp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + else + gp.copy_data (bp, bp_offset, gp_offset, bn) + gp.fill_with (0, gp_offset + bn, mn - bn - gp_offset - 1) + end + end + create xp.make_filled (0, mn) + sqr_n (tp, tp_offset, gp, gp_offset, mn) + if use_redc then + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + this_gp := gp + this_gp_offset := gp_offset + from + i := 1 + until + i >= big_k // 2 + loop + mul_n (tp, tp_offset, this_gp, this_gp_offset, xp, xp_offset, mn) + this_gp_offset := this_gp_offset + mn + if use_redc then + redc_basecase (this_gp, this_gp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, this_gp, this_gp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + i := i + 1 + end + ep := e.item + i := en - 1 + c := ep [ep_offset + i] + sh := limb_bits - e_zero_cnt + sh := sh - small_k + if sh < 0 then + if i > 0 then + i := i - 1 + c := c |<< (-sh) + sh := sh + limb_bits + c := c.bit_or (ep [ep_offset + i] |>> sh) + end + else + c := c |>> sh + end + from + j := 0 + until + c \\ 2 /= 0 + loop + c := c |>> 1 + j := j + 1 + end + xp.copy_data (gp, gp_offset + mn * (c |>> 1).to_integer_32, xp_offset, mn) + from + j := j - 1 + until + j < 0 + loop + sqr_n (tp, tp_offset, xp, xp_offset, mn) + if use_redc then + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + j := j - 1 + end + from + until + i <= 0 and sh <= 0 + loop + c := ep [ep_offset + i] + l := small_k + sh := sh - l + if sh < 0 then + if i > 0 then + i := i - 1 + c := c |<< (-sh) + sh := sh + limb_bits + c := c.bit_or (ep [ep_offset + i] |>> sh) + else + l := l + sh + end + else + c := c |>> sh + end + c := c.bit_and (((1).to_natural_32 |<< l) - 1) + from + until + (c |>> (l - 1)) /= 0 or (i <= 0 and sh <= 0) + loop + sqr_n (tp, tp_offset, xp, xp_offset, mn) + if use_redc then + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + if sh /= 0 then + sh := sh - 1 + c := (c |<< 1) + ((ep [ep_offset + i] |>> sh).bit_and (1)) + else + i := i - 1 + sh := limb_bits - 1 + c := (c |<< 1) + (ep [ep_offset + i] |>> sh) + end + end + if c /= 0 then + from + j := 0 + until + c \\ 2 /= 0 + loop + c := c |>> 1 + j := j + 1 + end + l := l - j + from + l := l - 1 + until + l < 0 + loop + sqr_n (tp, tp_offset, xp, xp_offset, mn) + if use_redc then + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + l := l - 1 + end + mul_n (tp, tp_offset, xp, xp_offset, gp, gp_offset + mn * (c |>> 1).to_integer_32, mn) + if use_redc then + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + else + j := l + end + from + j := j - 1 + until + j < 0 + loop + sqr_n (tp, tp_offset, xp, xp_offset, mn) + if use_redc then + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, 2 * mn, mp, mp_offset, mn) + end + j := j - 1 + end + end + if use_redc then + tp.copy_data (xp, xp_offset, tp_offset, mn) + tp.fill_with (0, tp_offset + mn, tp_offset + mn + mn - 1) + redc_basecase (xp, xp_offset, mp, mp_offset, mn, invm, tp, tp_offset) + if cmp_special (xp, xp_offset, mp, mp_offset, mn) >= 0 then + sub_n (xp, xp_offset, xp, xp_offset, mp, mp_offset, mn, carry) + junk := carry.item + end + else + if m_zero_cnt /= 0 then + lshift (tp, tp_offset, xp, xp_offset, mn, m_zero_cnt, carry) + cy := carry.item + tp [tp_offset + mn] := cy + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, mn + (cy /= 0).to_integer, mp, mp_offset, mn) + rshift (xp, xp_offset, xp, xp_offset, mn, m_zero_cnt, carry) + junk := carry.item + end + end + xn := mn + xn := normalize (xp, xp_offset, xn) + if ep [ep_offset].bit_and (1) /= 0 and b.count < 0 and xn /= 0 then + mp := m.item + sub_special (xp, xp_offset, mp, mp_offset, mn, xp, xp_offset, xn, carry) + junk := carry.item + xn := mn + xn := normalize (xp, xp_offset, xn) + end + r.resize (xn) + r.count := xn + r.item.copy_data (xp, xp_offset, 0, xn) + end + end + + powm_ui (target: READABLE_INTEGER_X; b: READABLE_INTEGER_X; el: NATURAL_32; m: READABLE_INTEGER_X) + local + xp: SPECIAL [NATURAL_32] + xp_offset: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + qp: SPECIAL [NATURAL_32] + qp_offset: INTEGER + mp: SPECIAL [NATURAL_32] + mp_offset: INTEGER + bp: SPECIAL [NATURAL_32] + bp_offset: INTEGER + xn: INTEGER + tn: INTEGER + mn: INTEGER + bn: INTEGER + m_zero_count: INTEGER + c: INTEGER + e: NATURAL_32 + new_mp: SPECIAL [NATURAL_32] + junk: NATURAL_32 + new_bp: SPECIAL [NATURAL_32] + cy: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + mp := m.item + mn := m.count.abs + if mn = 0 then + (create {DIVIDE_BY_ZERO}).raise + end + if el = 0 then + target.count := (not (mn = 1 and then mp [mp_offset] = 1)).to_integer + target.item [0] := 1 + else + m_zero_count := leading_zeros (mp [mp_offset + mn - 1]) + if m_zero_count /= 0 then + create new_mp.make_filled (0, mn) + lshift (new_mp, 0, mp, mp_offset, mn, m_zero_count, carry) + junk := carry.item + mp := new_mp + end + bn := b.count.abs + bp := b.item + if bn > mn then + create new_bp.make_filled (0, mn) + reduce (new_bp, 0, bp, bp_offset, bn, mp, mp_offset, mn) + bp := new_bp + bn := mn + bn := normalize (bp, 0, bn) + end + if bn = 0 then + target.count := 0 + else + create tp.make_filled (0, 2 * mn + 1) + create xp.make_filled (0, mn) + create qp.make_filled (0, mn + 1) + xp.copy_data (bp, bp_offset, xp_offset, bn) + xn := bn + e := el + c := leading_zeros (e) + e := (e |<< c) |<< 1 + c := limb_bits - 1 - c + if c = 0 and then xn = mn and cmp_special (xp, xp_offset, mp, mp_offset, mn) >= 0 then + sub_n (xp, xp_offset, xp, xp_offset, mp, mp_offset, mn, carry) + junk := carry.item + else + from + until + c = 0 + loop + sqr_n (tp, tp_offset, xp, xp_offset, xn) + tn := 2 * xn + tn := tn - (tp [tp_offset + tn - 1] = 0).to_integer + if tn < mn then + xp.copy_data (tp, tp_offset, xp_offset, tn) + xn := tn + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, tn, mp, mp_offset, mn) + xn := mn + end + if e.to_integer_32 < 0 then + mul_special (tp, tp_offset, xp, xp_offset, xn, bp, bp_offset, bn, carry) + junk := carry.item + tn := xn + bn + tn := tn - (tp [tp_offset + tn - 1] = 0).to_integer + if tn < mn then + xp.copy_data (tp, tp_offset, xp_offset, tn) + xn := tn + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, tn, mp, mp_offset, mn) + xn := mn + end + end + e := e |<< 1 + c := c - 1 + end + end + if m_zero_count /= 0 then + lshift (tp, tp_offset, xp, xp_offset, xn, m_zero_count, carry) + cy := carry.item + tp [tp_offset + xn] := cy + xn := xn + (cy /= 0).to_integer + if xn < mn then + xp.copy_data (tp, tp_offset, xp_offset, xn) + else + tdiv_qr_special (qp, qp_offset, xp, xp_offset, tp, tp_offset, xn, mp, mp_offset, mn) + xn := mn + end + rshift (xp, xp_offset, xp, xp_offset, xn, m_zero_count, carry) + junk := carry.item + end + xn := normalize (xp, xp_offset, xn) + if el.bit_test (0) and b.count < 0 and xn /= 0 then + mp := m.item + mp_offset := 0 + sub_special (xp, xp_offset, mp, mp_offset, mn, xp, xp_offset, xn, carry) + junk := carry.item + xn := mn + xn := normalize (xp, xp_offset, xn) + end + target.resize (xn) + target.count := xn + target.item.copy_data (xp, xp_offset, 0, xn) + end + end + end + + probab_prime_isprime (t: NATURAL_32): BOOLEAN + local + q: NATURAL_32 + r: NATURAL_32 + d: NATURAL_32 + do + if t < 3 or not t.bit_test (0) then + Result := t = 2 + else + from + d := 3 + r := 1 + q := d + until + Result or r = 0 + loop + q := t // d + r := t - q * d + Result := (q < d) + d := d + 2 + end + end + end + + probab_prime_p (op1_a: READABLE_INTEGER_X; reps: INTEGER): INTEGER + local + r: NATURAL_32 + n2: INTEGER_X + is_prime: BOOLEAN + op1: READABLE_INTEGER_X + done: BOOLEAN + ln2: NATURAL_32 + q: NATURAL_32 + p1: CELL [NATURAL_32] + p0: CELL [NATURAL_32] + p: NATURAL_32 + primes: SPECIAL [NATURAL_32] + nprimes: INTEGER + do + create p1.put (0) + create p0.put (0) + create primes.make_filled (0, 15) + op1 := op1_a + create n2 + if cmp_ui (op1, 1_000_000) <= 0 then + if cmpabs_ui (op1, 1_000_000) <= 0 then + is_prime := probab_prime_isprime (op1.as_natural_32) + if is_prime then + Result := 2 + else + Result := 0 + end + done := True + else + n2.item := op1.item + n2.count := -op1.count + op1 := n2 + end + end + if not done then + if not op1.as_natural_32.bit_test (0) then + done := True + end + end + if not done then + r := preinv_mod_1 (op1.item, 0, op1.count, pp, pp_inverted) + if r \\ 3 = 0 or r \\ 5 = 0 or r \\ 7 = 0 or r \\ 11 = 0 or r \\ 13 = 0 or r \\ 17 = 0 or r \\ 19 = 0 or r \\ 23 = 0 or r \\ 29 = 0 then + Result := 0 + done := True + end + end + if not done then + nprimes := 0 + p := 1 + ln2 := sizeinbase (op1, 2).to_natural_32 + from + q := pp_first_omitted.to_natural_32 + until + q >= ln2 or done + loop + if probab_prime_isprime (q) then + umul_ppmm (p1, p0, p, q) + if p1.item /= 0 then + r := modexact_1c_odd (op1.item, 0, op1.count, p, 0) + from + nprimes := nprimes - 1 + until + nprimes < 0 or done + loop + if r \\ primes [nprimes] = 0 then + Result := 0 + done := True + end + nprimes := nprimes - 1 + end + p := q + nprimes := 0 + else + p := p0.item + end + primes [nprimes] := q + nprimes := nprimes + 1 + end + q := q + 2 + end + end + if not done then + Result := millerrabin (op1, reps) + end + end + + pp: NATURAL_32 = 0xC0CFD797 + pp_inverted: NATURAL_32 = 0x53E5645C + pp_first_omitted: INTEGER = 31 + + reduce (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; ap_count: INTEGER; mp: SPECIAL [NATURAL_32]; mp_offset: INTEGER; mp_count: INTEGER) + local + tmp: SPECIAL [NATURAL_32] + do + create tmp.make_filled (0, ap_count - mp_count + 1) + tdiv_qr_special (tmp, 0, target, target_offset, ap, ap_offset, ap_count, mp, mp_offset, mp_count) + end + + muldiv (target: READABLE_INTEGER_X; inc: INTEGER_32; rsize: CELL [INTEGER_32]; ralloc: CELL [INTEGER_32]; nacc: CELL [NATURAL_32]; kacc: CELL [NATURAL_32]) + local + new_ralloc: INTEGER_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + if rsize.item <= ralloc.item then + new_ralloc := ralloc.item + inc + target.resize (new_ralloc) + ralloc.put (new_ralloc) + end + mul_1 (target.item, 0, target.item, 0, rsize.item, nacc.item, carry) + target.item [rsize.item] := carry.item + divexact_1 (target.item, 0, target.item, 0, rsize.item + 1, kacc.item) + if target.item [rsize.item] /= 0 then + rsize.put (rsize.item + 1) + end + end + + invert_gf (target: READABLE_INTEGER_X op1: READABLE_INTEGER_X op2: READABLE_INTEGER_X) + require + not op1.is_negative + not op2.is_negative + local + target_special: SPECIAL [NATURAL_32] + op2_count: INTEGER + do + target.resize (op2.count) + op2_count := op2.count + target_special := target.item + invert_gf_special (target_special, 0, op1.item, 0, op1.count, op2.item, 0, op2_count) + target.count := normalize (target_special, 0, op2_count) + end +end diff --git a/library/crypto/eapml/facilities/integer_x_random.e b/library/crypto/eapml/facilities/integer_x_random.e new file mode 100644 index 00000000..aca0b884 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_random.e @@ -0,0 +1,108 @@ +note + description: "Summary description for {INTEGER_X_RANDOM}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Letting lawyers make laws is like letting doctors make diseases. - Anonymous" + +deferred class + INTEGER_X_RANDOM + +inherit + INTEGER_X_FACILITIES + LIMB_MANIPULATION + SPECIAL_COMPARISON + SPECIAL_ARITHMETIC + SPECIAL_UTILITY + +feature + + urandomb (target: READABLE_INTEGER_X; state: RANDOM_NUMBER_GENERATOR; nbits: INTEGER) + -- Generate a uniformly distributed random integer in the range 0 to 2^`n'-1, inclusive. + -- `state' must be initialized by calling one of the randinit functions before invoking this function. + local + size: INTEGER_32 + do + size := bits_to_limbs (nbits) + target.resize (size) + state.randget (target.item, 0, nbits) + size := normalize (target.item, 0, size) + target.count := size + ensure + target.bits <= nbits + end + + urandomm (target: READABLE_INTEGER_X; state: RANDOM_NUMBER_GENERATOR; n: READABLE_INTEGER_X) + -- Generate a uniform random integer in the range 0 to n-1, inclusive. + -- `state' must be initialized by calling one of the randinit functions before invoking this function. + local + rp: SPECIAL [NATURAL_32] + rp_offset: INTEGER + np: SPECIAL [NATURAL_32] + np_offset: INTEGER + nlast: INTEGER + nbits: INTEGER + size: INTEGER + count: INTEGER + pow2: BOOLEAN + cmp_l: INTEGER + overlap: BOOLEAN + junk: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + size := n.count.abs + if size = 0 then + (create {DIVIDE_BY_ZERO}).raise + end + np := n.item + nlast := size - 1 + pow2 := pow2_p (n.item [nlast]) + if pow2 then + from + np := n.item + until + not pow2 or np_offset >= nlast + loop + if np [np_offset] /= 0 then + pow2 := False + end + np_offset := np_offset + 1 + end + end + count := leading_zeros (np [nlast]) + nbits := size * limb_bits - (count) - pow2.to_integer + if nbits = 0 then + target.count := 0 + else + np := n.item + np_offset := 0 + rp := target.item + rp_offset := 0 + if np = rp then + overlap := True + create np.make_filled (0, size) + np.copy_data (n.item, 0, 0, size) + end + target.resize (size) + rp := target.item + rp [rp_offset + size - 1] := 0 + count := 80 + from + cmp_l := 0 + until + cmp_l < 0 or count = 0 + loop + state.randget (rp, rp_offset, nbits) + cmp_l := cmp (rp, rp_offset, np, np_offset, size) + count := count - 1 + end + if count = 0 then + sub_n (rp, rp_offset, rp, rp_offset, np, np_offset, size, carry) + junk := carry.item + end + size := normalize (rp, rp_offset, size) + target.count := size + end + end +end diff --git a/library/crypto/eapml/facilities/integer_x_sizing.e b/library/crypto/eapml/facilities/integer_x_sizing.e new file mode 100644 index 00000000..b9d322a0 --- /dev/null +++ b/library/crypto/eapml/facilities/integer_x_sizing.e @@ -0,0 +1,49 @@ +note + description: "Summary description for {INTEGER_X_SIZING}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "My freedom is more important than your great idea. - Anonymous" + +deferred class + INTEGER_X_SIZING + +inherit + INTEGER_X_FACILITIES + LIMB_BIT_SCANNING + LIMB_MANIPULATION + MP_BASES + +feature + + sizeinbase (op: READABLE_INTEGER_X; base: INTEGER): INTEGER_32 + -- Return the size of `op' measured in number of digits in the given base. + -- `base' can vary from 2 to 62. + -- The sign of `op' is ignored, just the absolute value is used. + -- The result will be either exact or 1 too big. + -- If `base' is a power of 2, the result is always exact. + -- If `op' is zero the return value is always 1. + -- This function can be used to determine the space required when converting `op' to a string. + -- The right amount of allocation is normally two more than the value returned, one extra for + -- a minus sign and one for the null-terminator. + -- It will be noted that `sizeinbase(op,2)' can be used to locate the most significant 1 + -- bit in `op', counting from 1. (Unlike the bitwise functions which start from 0. + local + lb_base: NATURAL_32 + cnt: INTEGER_32 + totbits: INTEGER_32 + do + if op.count.abs = 0 then + Result := 1 + else + cnt := leading_zeros (op.item [op.count.abs - 1]) + totbits := op.count.abs * limb_bits - cnt + if pow2_p (base.to_natural_32) then + lb_base := big_base (base) + Result := (totbits + lb_base.to_integer_32 - 1) // lb_base.to_integer_32 + else + Result := ((totbits.to_double * chars_per_bit_exactly (base)) + 1).truncated_to_integer + end + end + end +end diff --git a/library/crypto/eapml/facilities/mp_bases.e b/library/crypto/eapml/facilities/mp_bases.e new file mode 100644 index 00000000..b5595f49 --- /dev/null +++ b/library/crypto/eapml/facilities/mp_bases.e @@ -0,0 +1,1603 @@ +note + description: "Statistics about each base representation" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "As the growing emphasis on feelings crowds out reason, facts will play a smaller role in public discourse. - Paul Craig Roberts" + +deferred class + MP_BASES + +feature + + chars_per_limb (base: INTEGER): INTEGER + -- Number of printed characters per limb truncated down in base `base' + require + base >= 2 + base <= 256 + do + inspect base + when 2 then + Result := 32 + when 3 then + Result := 20 + when 4 then + Result := 16 + when 5 then + Result := 13 + when 6 then + Result := 12 + when 7 then + Result := 11 + when 8..9 then + Result := 10 + when 10..11 then + Result := 9 + when 12..16 then + Result := 8 + when 17..23 then + Result := 7 + when 24..40 then + Result := 6 + when 41..84 then + Result := 5 + when 85..256 then + Result := 4 + end + end + + chars_per_bit_exactly (base: INTEGER): REAL_64 + -- Exact number of characters per bit in base `base' + require + base >= 2 + base <= 256 + do + inspect base + when 2 then + Result := 1.0000000000000000 + when 3 then + Result := 0.6309297535714574 + when 4 then + Result := 0.5000000000000000 + when 5 then + Result := 0.4306765580733931 + when 6 then + Result := 0.3868528072345416 + when 7 then + Result := 0.3562071871080222 + when 8 then + Result := 0.3333333333333334 + when 9 then + Result := 0.3154648767857287 + when 10 then + Result := 0.3010299956639811 + when 11 then + Result := 0.2890648263178878 + when 12 then + Result := 0.2789429456511298 + when 13 then + Result := 0.2702381544273197 + when 14 then + Result := 0.2626495350371936 + when 15 then + Result := 0.2559580248098155 + when 16 then + Result := 0.2500000000000000 + when 17 then + Result := 0.2446505421182260 + when 18 then + Result := 0.2398124665681315 + when 19 then + Result := 0.2354089133666382 + when 20 then + Result := 0.2313782131597592 + when 21 then + Result := 0.2276702486969530 + when 22 then + Result := 0.2242438242175754 + when 23 then + Result := 0.2210647294575037 + when 24 then + Result := 0.2181042919855316 + when 25 then + Result := 0.2153382790366965 + when 26 then + Result := 0.2127460535533632 + when 27 then + Result := 0.2103099178571525 + when 28 then + Result := 0.2080145976765095 + when 29 then + Result := 0.2058468324604345 + when 30 then + Result := 0.2037950470905062 + when 31 then + Result := 0.2018490865820999 + when 32 then + Result := 0.2000000000000000 + when 33 then + Result := 0.1982398631705605 + when 34 then + Result := 0.1965616322328226 + when 35 then + Result := 0.1949590218937863 + when 36 then + Result := 0.1934264036172708 + when 37 then + Result := 0.1919587200065601 + when 38 then + Result := 0.1905514124267734 + when 39 then + Result := 0.1892003595168700 + when 40 then + Result := 0.1879018247091076 + when 41 then + Result := 0.1866524112389434 + when 42 then + Result := 0.1854490234153689 + when 43 then + Result := 0.1842888331487062 + when 44 then + Result := 0.1831692509136336 + when 45 then + Result := 0.1820879004699383 + when 46 then + Result := 0.1810425967800402 + when 47 then + Result := 0.1800313266566926 + when 48 then + Result := 0.1790522317510414 + when 49 then + Result := 0.1781035935540111 + when 50 then + Result := 0.1771838201355579 + when 51 then + Result := 0.1762914343888821 + when 52 then + Result := 0.1754250635819545 + when 53 then + Result := 0.1745834300480449 + when 54 then + Result := 0.1737653428714400 + when 55 then + Result := 0.1729696904450771 + when 56 then + Result := 0.1721954337940981 + when 57 then + Result := 0.1714416005739134 + when 58 then + Result := 0.1707072796637201 + when 59 then + Result := 0.1699916162869140 + when 60 then + Result := 0.1692938075987814 + when 61 then + Result := 0.1686130986895011 + when 62 then + Result := 0.1679487789570419 + when 63 then + Result := 0.1673001788101741 + when 64 then + Result := 0.1666666666666667 + when 65 then + Result := 0.1660476462159378 + when 66 then + Result := 0.1654425539190583 + when 67 then + Result := 0.1648508567221604 + when 68 then + Result := 0.1642720499620502 + when 69 then + Result := 0.1637056554452156 + when 70 then + Result := 0.1631512196835108 + when 71 then + Result := 0.1626083122716341 + when 72 then + Result := 0.1620765243931223 + when 73 then + Result := 0.1615554674429964 + when 74 then + Result := 0.1610447717564444 + when 75 then + Result := 0.1605440854340214 + when 76 then + Result := 0.1600530732548214 + when 77 then + Result := 0.1595714156699382 + when 78 then + Result := 0.1590988078692942 + when 79 then + Result := 0.1586349589155960 + when 80 then + Result := 0.1581795909397823 + when 81 then + Result := 0.1577324383928644 + when 82 then + Result := 0.1572932473495469 + when 83 then + Result := 0.1568617748594410 + when 84 then + Result := 0.1564377883420716 + when 85 then + Result := 0.1560210650222250 + when 86 then + Result := 0.1556113914024940 + when 87 then + Result := 0.1552085627701551 + when 88 then + Result := 0.1548123827357682 + when 89 then + Result := 0.1544226628011101 + when 90 then + Result := 0.1540392219542636 + when 91 then + Result := 0.1536618862898642 + when 92 then + Result := 0.1532904886526781 + when 93 then + Result := 0.1529248683028321 + when 94 then + Result := 0.1525648706011593 + when 95 then + Result := 0.1522103467132434 + when 96 then + Result := 0.1518611533308632 + when 97 then + Result := 0.1515171524096389 + when 98 then + Result := 0.1511782109217764 + when 99 then + Result := 0.1508442006228941 + when 100 then + Result := 0.1505149978319906 + when 101 then + Result := 0.1501904832236879 + when 102 then + Result := 0.1498705416319474 + when 103 then + Result := 0.1495550618645152 + when 104 then + Result := 0.1492439365274121 + when 105 then + Result := 0.1489370618588283 + when 106 then + Result := 0.1486343375718350 + when 107 then + Result := 0.1486343375718350 + when 108 then + Result := 0.1480409554829326 + when 109 then + Result := 0.1477501131786861 + when 110 then + Result := 0.1474630519902391 + when 111 then + Result := 0.1471796869179853 + when 112 then + Result := 0.1468999356504447 + when 113 then + Result := 0.1466237184553111 + when 114 then + Result := 0.1463509580758620 + when 115 then + Result := 0.1460815796324244 + when 116 then + Result := 0.1458155105286054 + when 117 then + Result := 0.1455526803620167 + when 118 then + Result := 0.1452930208392428 + when 119 then + Result := 0.1450364656948130 + when 120 then + Result := 0.1447829506139581 + when 121 then + Result := 0.1445324131589439 + when 122 then + Result := 0.1442847926987864 + when 123 then + Result := 0.1440400303421672 + when 124 then + Result := 0.1437980688733775 + when 125 then + Result := 0.1435588526911310 + when 126 then + Result := 0.1433223277500932 + when 127 then + Result := 0.1430884415049874 + when 128 then + Result := 0.1428571428571429 + when 129 then + Result := 0.1426283821033600 + when 130 then + Result := 0.1424021108869747 + when 131 then + Result := 0.1421782821510107 + when 132 then + Result := 0.1419568500933153 + when 133 then + Result := 0.1417377701235801 + when 134 then + Result := 0.1415209988221527 + when 135 then + Result := 0.1413064939005528 + when 136 then + Result := 0.1410942141636095 + when 137 then + Result := 0.1408841194731412 + when 138 then + Result := 0.1406761707131039 + when 139 then + Result := 0.1404703297561400 + when 140 then + Result := 0.1402665594314587 + when 141 then + Result := 0.1400648234939879 + when 142 then + Result := 0.1398650865947379 + when 143 then + Result := 0.1396673142523192 + when 144 then + Result := 0.1394714728255649 + when 145 then + Result := 0.1392775294872041 + when 146 then + Result := 0.1390854521985406 + when 147 then + Result := 0.1388952096850913 + when 148 then + Result := 0.1387067714131417 + when 149 then + Result := 0.1385201075671775 + when 150 then + Result := 0.1383351890281540 + when 151 then + Result := 0.1381519873525671 + when 152 then + Result := 0.1379704747522905 + when 153 then + Result := 0.1377906240751463 + when 154 then + Result := 0.1376124087861776 + when 155 then + Result := 0.1374358029495937 + when 156 then + Result := 0.1372607812113589 + when 157 then + Result := 0.1370873187823978 + when 158 then + Result := 0.1369153914223921 + when 159 then + Result := 0.1367449754241439 + when 160 then + Result := 0.1365760475984821 + when 161 then + Result := 0.1364085852596902 + when 162 then + Result := 0.1362425662114337 + when 163 then + Result := 0.1360779687331669 + when 164 then + Result := 0.1359147715670014 + when 165 then + Result := 0.1357529539050150 + when 166 then + Result := 0.1355924953769863 + when 167 then + Result := 0.1354333760385373 + when 168 then + Result := 0.1352755763596663 + when 169 then + Result := 0.1351190772136599 + when 170 then + Result := 0.1349638598663645 + when 171 then + Result := 0.1348099059658079 + when 172 then + Result := 0.1346571975321549 + when 173 then + Result := 0.1345057169479844 + when 174 then + Result := 0.1343554469488779 + when 175 then + Result := 0.1342063706143054 + when 176 then + Result := 0.1340584713587980 + when 177 then + Result := 0.1339117329233981 + when 178 then + Result := 0.1337661393673756 + when 179 then + Result := 0.1336216750601997 + when 180 then + Result := 0.1334783246737591 + when 181 then + Result := 0.1333360731748201 + when 182 then + Result := 0.1331949058177136 + when 183 then + Result := 0.1330548081372441 + when 184 then + Result := 0.1329157659418126 + when 185 then + Result := 0.1327777653067443 + when 186 then + Result := 0.1326407925678156 + when 187 then + Result := 0.1325048343149731 + when 188 then + Result := 0.1323698773862368 + when 189 then + Result := 0.1322359088617821 + when 190 then + Result := 0.1321029160581950 + when 191 then + Result := 0.1319708865228925 + when 192 then + Result := 0.1318398080287045 + when 193 then + Result := 0.1317096685686114 + when 194 then + Result := 0.1315804563506306 + when 195 then + Result := 0.1314521597928493 + when 196 then + Result := 0.1313247675185968 + when 197 then + Result := 0.1311982683517524 + when 198 then + Result := 0.1310726513121844 + when 199 then + Result := 0.1309479056113158 + when 200 then + Result := 0.1308240206478128 + when 201 then + Result := 0.1307009860033912 + when 202 then + Result := 0.1305787914387386 + when 203 then + Result := 0.1304574268895465 + when 204 then + Result := 0.1303368824626505 + when 205 then + Result := 0.1302171484322746 + when 206 then + Result := 0.1300982152363760 + when 207 then + Result := 0.1299800734730872 + when 208 then + Result := 0.1298627138972530 + when 209 then + Result := 0.1297461274170591 + when 210 then + Result := 0.1296303050907487 + when 211 then + Result := 0.1295152381234257 + when 212 then + Result := 0.1294009178639407 + when 213 then + Result := 0.1292873358018581 + when 214 then + Result := 0.1291744835645007 + when 215 then + Result := 0.1290623529140715 + when 216 then + Result := 0.1289509357448472 + when 217 then + Result := 0.1288402240804449 + when 218 then + Result := 0.1287302100711567 + when 219 then + Result := 0.1286208859913518 + when 220 then + Result := 0.1285122442369443 + when 221 then + Result := 0.1284042773229231 + when 222 then + Result := 0.1282969778809442 + when 223 then + Result := 0.1281903386569819 + when 224 then + Result := 0.1280843525090381 + when 225 then + Result := 0.1279790124049078 + when 226 then + Result := 0.1278743114199984 + when 227 then + Result := 0.1277702427352035 + when 228 then + Result := 0.1276667996348261 + when 229 then + Result := 0.1275639755045533 + when 230 then + Result := 0.1274617638294791 + when 231 then + Result := 0.1273601581921741 + when 232 then + Result := 0.1272591522708010 + when 233 then + Result := 0.1271587398372755 + when 234 then + Result := 0.1270589147554692 + when 235 then + Result := 0.1269596709794558 + when 236 then + Result := 0.1268610025517973 + when 237 then + Result := 0.1267629036018709 + when 238 then + Result := 0.1266653683442337 + when 239 then + Result := 0.1265683910770258 + when 240 then + Result := 0.1264719661804097 + when 241 then + Result := 0.1263760881150453 + when 242 then + Result := 0.1262807514205999 + when 243 then + Result := 0.1261859507142915 + when 244 then + Result := 0.1260916806894653 + when 245 then + Result := 0.1259979361142023 + when 246 then + Result := 0.1259047118299582 + when 247 then + Result := 0.1258120027502338 + when 248 then + Result := 0.1257198038592741 + when 249 then + Result := 0.1256281102107963 + when 250 then + Result := 0.1255369169267456 + when 251 then + Result := 0.1254462191960791 + when 252 then + Result := 0.1253560122735751 + when 253 then + Result := 0.1252662914786691 + when 254 then + Result := 0.1251770521943144 + when 255 then + Result := 0.1250882898658682 + when 256 then + Result := 0.1250000000000000 + end + end + + big_base (base: INTEGER): NATURAL + do + inspect base + when 2 then + Result := 0x00000001 + when 3 then + Result := 0xcfd41b91 + when 4 then + Result := 0x00000002 + when 5 then + Result := 0x48c27395 + when 6 then + Result := 0x81bf1000 + when 7 then + Result := 0x75db9c97 + when 8 then + Result := 0x00000003 + when 9 then + Result := 0xcfd41b91 + when 10 then + Result := 0x3b9aca00 + when 11 then + Result := 0x8c8b6d2b + when 12 then + Result := 0x19a10000 + when 13 then + Result := 0x309f1021 + when 14 then + Result := 0x57f6c100 + when 15 then + Result := 0x98c29b81 + when 16 then + Result := 0x00000004 + when 17 then + Result := 0x18754571 + when 18 then + Result := 0x247dbc80 + when 19 then + Result := 0x3547667b + when 20 then + Result := 0x4c4b4000 + when 21 then + Result := 0x6b5a6e1d + when 22 then + Result := 0x94ace180 + when 23 then + Result := 0xcaf18367 + when 24 then + Result := 0x0b640000 + when 25 then + Result := 0x0e8d4a51 + when 26 then + Result := 0x1269ae40 + when 27 then + Result := 0x17179149 + when 28 then + Result := 0x1cb91000 + when 29 then + Result := 0x23744899 + when 30 then + Result := 0x2b73a840 + when 31 then + Result := 0x34e63b41 + when 32 then + Result := 0x00000005 + when 33 then + Result := 0x4cfa3cc1 + when 34 then + Result := 0x5c13d840 + when 35 then + Result := 0x6d91b519 + when 36 then + Result := 0x81bf1000 + when 37 then + Result := 0x98ede0c9 + when 38 then + Result := 0xb3773e40 + when 39 then + Result := 0xd1bbc4d1 + when 40 then + Result := 0xf4240000 + when 41 then + Result := 0x06e7d349 + when 42 then + Result := 0x07ca30a0 + when 43 then + Result := 0x08c32bbb + when 44 then + Result := 0x09d46c00 + when 45 then + Result := 0x0affacfd + when 46 then + Result := 0x0c46bee0 + when 47 then + Result := 0x0dab86ef + when 48 then + Result := 0x0f300000 + when 49 then + Result := 0x10d63af1 + when 50 then + Result := 0x12a05f20 + when 51 then + Result := 0x1490aae3 + when 52 then + Result := 0x16a97400 + when 53 then + Result := 0x18ed2825 + when 54 then + Result := 0x1b5e4d60 + when 55 then + Result := 0x1dff8297 + when 56 then + Result := 0x20d38000 + when 57 then + Result := 0x23dd1799 + when 58 then + Result := 0x271f35a0 + when 59 then + Result := 0x2a9ce10b + when 60 then + Result := 0x2e593c00 + when 61 then + Result := 0x3257844d + when 62 then + Result := 0x369b13e0 + when 63 then + Result := 0x3b27613f + when 64 then + Result := 0x00000006 + when 65 then + Result := 0x4528a141 + when 66 then + Result := 0x4aa51420 + when 67 then + Result := 0x50794633 + when 68 then + Result := 0x56a94400 + when 69 then + Result := 0x5d393975 + when 70 then + Result := 0x642d7260 + when 71 then + Result := 0x6b8a5ae7 + when 72 then + Result := 0x73548000 + when 73 then + Result := 0x7b908fe9 + when 74 then + Result := 0x84435aa0 + when 75 then + Result := 0x8d71d25b + when 76 then + Result := 0x97210c00 + when 77 then + Result := 0xa1563f9d + when 78 then + Result := 0xac16c8e0 + when 79 then + Result := 0xb768278f + when 80 then + Result := 0xc3500000 + when 81 then + Result := 0xcfd41b91 + when 82 then + Result := 0xdcfa6920 + when 83 then + Result := 0xeac8fd83 + when 84 then + Result := 0xf9461400 + when 85 then + Result := 0x031c84b1 + when 86 then + Result := 0x0342ab10 + when 87 then + Result := 0x036a2c21 + when 88 then + Result := 0x03931000 + when 89 then + Result := 0x03bd5ee1 + when 90 then + Result := 0x03e92110 + when 91 then + Result := 0x04165ef1 + when 92 then + Result := 0x04452100 + when 93 then + Result := 0x04756fd1 + when 94 then + Result := 0x04a75410 + when 95 then + Result := 0x04dad681 + when 96 then + Result := 0x05100000 + when 97 then + Result := 0x0546d981 + when 98 then + Result := 0x057f6c10 + when 99 then + Result := 0x05b9c0d1 + when 100 then + Result := 0x05f5e100 + when 101 then + Result := 0x0633d5f1 + when 102 then + Result := 0x0673a910 + when 103 then + Result := 0x06b563e1 + when 104 then + Result := 0x06f91000 + when 105 then + Result := 0x073eb721 + when 106 then + Result := 0x07866310 + when 107 then + Result := 0x07866310 + when 108 then + Result := 0x081bf100 + when 109 then + Result := 0x0869e711 + when 110 then + Result := 0x08ba0a10 + when 111 then + Result := 0x090c6441 + when 112 then + Result := 0x09610000 + when 113 then + Result := 0x09b7e7c1 + when 114 then + Result := 0x0a112610 + when 115 then + Result := 0x0a6cc591 + when 116 then + Result := 0x0acad100 + when 117 then + Result := 0x0b2b5331 + when 118 then + Result := 0x0b8e5710 + when 119 then + Result := 0x0bf3e7a1 + when 120 then + Result := 0x0c5c1000 + when 121 then + Result := 0x0cc6db61 + when 122 then + Result := 0x0d345510 + when 123 then + Result := 0x0da48871 + when 124 then + Result := 0x0e178100 + when 125 then + Result := 0x0e8d4a51 + when 126 then + Result := 0x0f05f010 + when 127 then + Result := 0x0f817e01 + when 128 then + Result := 0x00000007 + when 129 then + Result := 0x10818201 + when 130 then + Result := 0x11061010 + when 131 then + Result := 0x118db651 + when 132 then + Result := 0x12188100 + when 133 then + Result := 0x12a67c71 + when 134 then + Result := 0x1337b510 + when 135 then + Result := 0x13cc3761 + when 136 then + Result := 0x14641000 + when 137 then + Result := 0x14ff4ba1 + when 138 then + Result := 0x159df710 + when 139 then + Result := 0x16401f31 + when 140 then + Result := 0x16e5d100 + when 141 then + Result := 0x178f1991 + when 142 then + Result := 0x183c0610 + when 143 then + Result := 0x18eca3c1 + when 144 then + Result := 0x19a10000 + when 145 then + Result := 0x1a592841 + when 146 then + Result := 0x1b152a10 + when 147 then + Result := 0x1bd51311 + when 148 then + Result := 0x1c98f100 + when 149 then + Result := 0x1d60d1b1 + when 150 then + Result := 0x1e2cc310 + when 151 then + Result := 0x1efcd321 + when 152 then + Result := 0x1fd11000 + when 153 then + Result := 0x20a987e1 + when 154 then + Result := 0x21864910 + when 155 then + Result := 0x226761f1 + when 156 then + Result := 0x234ce100 + when 157 then + Result := 0x2436d4d1 + when 158 then + Result := 0x25254c10 + when 159 then + Result := 0x26185581 + when 160 then + Result := 0x27100000 + when 161 then + Result := 0x280c5a81 + when 162 then + Result := 0x290d7410 + when 163 then + Result := 0x2a135bd1 + when 164 then + Result := 0x2b1e2100 + when 165 then + Result := 0x2c2dd2f1 + when 166 then + Result := 0x2d428110 + when 167 then + Result := 0x2e5c3ae1 + when 168 then + Result := 0x2f7b1000 + when 169 then + Result := 0x309f1021 + when 170 then + Result := 0x31c84b10 + when 171 then + Result := 0x32f6d0b1 + when 172 then + Result := 0x342ab100 + when 173 then + Result := 0x3563fc11 + when 174 then + Result := 0x36a2c210 + when 175 then + Result := 0x37e71341 + when 176 then + Result := 0x39310000 + when 177 then + Result := 0x3a8098c1 + when 178 then + Result := 0x3bd5ee10 + when 179 then + Result := 0x3d311091 + when 180 then + Result := 0x3e921100 + when 181 then + Result := 0x3ff90031 + when 182 then + Result := 0x4165ef10 + when 183 then + Result := 0x42d8eea1 + when 184 then + Result := 0x44521000 + when 185 then + Result := 0x45d16461 + when 186 then + Result := 0x4756fd10 + when 187 then + Result := 0x48e2eb71 + when 188 then + Result := 0x4a754100 + when 189 then + Result := 0x4c0e0f51 + when 190 then + Result := 0x4dad6810 + when 191 then + Result := 0x4f535d01 + when 192 then + Result := 0x51000000 + when 193 then + Result := 0x52b36301 + when 194 then + Result := 0x546d9810 + when 195 then + Result := 0x562eb151 + when 196 then + Result := 0x57f6c100 + when 197 then + Result := 0x59c5d971 + when 198 then + Result := 0x5b9c0d10 + when 199 then + Result := 0x5d796e61 + when 200 then + Result := 0x5f5e1000 + when 201 then + Result := 0x614a04a1 + when 202 then + Result := 0x633d5f10 + when 203 then + Result := 0x65383231 + when 204 then + Result := 0x673a9100 + when 205 then + Result := 0x69448e91 + when 206 then + Result := 0x6b563e10 + when 207 then + Result := 0x6d6fb2c1 + when 208 then + Result := 0x6f910000 + when 209 then + Result := 0x71ba3941 + when 210 then + Result := 0x73eb7210 + when 211 then + Result := 0x7624be11 + when 212 then + Result := 0x78663100 + when 213 then + Result := 0x7aafdeb1 + when 214 then + Result := 0x7d01db10 + when 215 then + Result := 0x7f5c3a21 + when 216 then + Result := 0x81bf1000 + when 217 then + Result := 0x842a70e1 + when 218 then + Result := 0x869e7110 + when 219 then + Result := 0x891b24f1 + when 220 then + Result := 0x8ba0a100 + when 221 then + Result := 0x8e2ef9d1 + when 222 then + Result := 0x90c64410 + when 223 then + Result := 0x93669481 + when 224 then + Result := 0x96100000 + when 225 then + Result := 0x98c29b81 + when 226 then + Result := 0x9b7e7c10 + when 227 then + Result := 0x9e43b6d1 + when 228 then + Result := 0xa1126100 + when 229 then + Result := 0xa3ea8ff1 + when 230 then + Result := 0xa6cc5910 + when 231 then + Result := 0xa9b7d1e1 + when 232 then + Result := 0xacad1000 + when 233 then + Result := 0xafac2921 + when 234 then + Result := 0xb2b53310 + when 235 then + Result := 0xb5c843b1 + when 236 then + Result := 0xb8e57100 + when 237 then + Result := 0xbc0cd111 + when 238 then + Result := 0xbf3e7a10 + when 239 then + Result := 0xc27a8241 + when 240 then + Result := 0xc5c10000 + when 241 then + Result := 0xc91209c1 + when 242 then + Result := 0xcc6db610 + when 243 then + Result := 0xcfd41b91 + when 244 then + Result := 0xd3455100 + when 245 then + Result := 0xd6c16d31 + when 246 then + Result := 0xda488710 + when 247 then + Result := 0xdddab5a1 + when 248 then + Result := 0xe1781000 + when 249 then + Result := 0xe520ad61 + when 250 then + Result := 0xe8d4a510 + when 251 then + Result := 0xec940e71 + when 252 then + Result := 0xf05f0100 + when 253 then + Result := 0xf4359451 + when 254 then + Result := 0xf817e010 + when 255 then + Result := 0xfc05fc01 + when 256 then + Result := 0x00000008 + end + end + + big_base_inverted (base: INTEGER): NATURAL + require + base >= 2 + base <= 256 + do + inspect base + when 2 then + Result := 0x00000000 + when 3 then + Result := 0x3b563c24 + when 4 then + Result := 0x00000000 + when 5 then + Result := 0xc25c2684 + when 6 then + Result := 0xf91bd1b6 + when 7 then + Result := 0x1607a2cb + when 8 then + Result := 0x00000000 + when 9 then + Result := 0x3b563c24 + when 10 then + Result := 0x12e0be82 + when 11 then + Result := 0xd24cde04 + when 12 then + Result := 0x3fa39ab5 + when 13 then + Result := 0x50f8ac5f + when 14 then + Result := 0x74843b1e + when 15 then + Result := 0xad0326c2 + when 16 then + Result := 0x00000000 + when 17 then + Result := 0x4ef0b6bd + when 18 then + Result := 0xc0fc48a1 + when 19 then + Result := 0x33838942 + when 20 then + Result := 0xad7f29ab + when 21 then + Result := 0x313c3d15 + when 22 then + Result := 0xb8cca9e0 + when 23 then + Result := 0x42ed6de9 + when 24 then + Result := 0x67980e0b + when 25 then + Result := 0x19799812 + when 26 then + Result := 0xbce85396 + when 27 then + Result := 0x62c103a9 + when 28 then + Result := 0x1d353d43 + when 29 then + Result := 0xce1decea + when 30 then + Result := 0x790fc511 + when 31 then + Result := 0x35b865a0 + when 32 then + Result := 0x00000000 + when 33 then + Result := 0xa9aed1b3 + when 34 then + Result := 0x63dfc229 + when 35 then + Result := 0x2b0fee30 + when 36 then + Result := 0xf91bd1b6 + when 37 then + Result := 0xac89c3a9 + when 38 then + Result := 0x6d2c32fe + when 39 then + Result := 0x387907c9 + when 40 then + Result := 0x0c6f7a0b + when 41 then + Result := 0x28928154 + when 42 then + Result := 0x06e8629d + when 43 then + Result := 0xd373dca0 + when 44 then + Result := 0xa0b17895 + when 45 then + Result := 0x746811a5 + when 46 then + Result := 0x4da6500f + when 47 then + Result := 0x2ba23582 + when 48 then + Result := 0x0db20a88 + when 49 then + Result := 0xe68d5ce4 + when 50 then + Result := 0xb7cdfd9d + when 51 then + Result := 0x8e583933 + when 52 then + Result := 0x697cc3ea + when 53 then + Result := 0x48a5ca6c + when 54 then + Result := 0x2b52db16 + when 55 then + Result := 0x111586a6 + when 56 then + Result := 0xf31d2b36 + when 57 then + Result := 0xc8d76d19 + when 58 then + Result := 0xa2cb1eb4 + when 59 then + Result := 0x807c3ec3 + when 60 then + Result := 0x617ec8bf + when 61 then + Result := 0x45746cbe + when 62 then + Result := 0x2c0aa273 + when 63 then + Result := 0x14f90805 + when 64 then + Result := 0x00000000 + when 65 then + Result := 0xd9cf0829 + when 66 then + Result := 0xb6fc4841 + when 67 then + Result := 0x973054cb + when 68 then + Result := 0x7a1dbe4b + when 69 then + Result := 0x5f7fcd7f + when 70 then + Result := 0x47196c84 + when 71 then + Result := 0x30b43635 + when 72 then + Result := 0x1c1fa5f6 + when 73 then + Result := 0x930634a + when 74 then + Result := 0xef7f4a3c + when 75 then + Result := 0xcf5552d2 + when 76 then + Result := 0xb1a47c8e + when 77 then + Result := 0x9634b43e + when 78 then + Result := 0x7cd3817d + when 79 then + Result := 0x65536761 + when 80 then + Result := 0x4f8b588e + when 81 then + Result := 0x3b563c24 + when 82 then + Result := 0x28928154 + when 83 then + Result := 0x1721bfb0 + when 84 then + Result := 0x06e8629d + when 85 then + Result := 0x491cc17c + when 86 then + Result := 0x3a11d83b + when 87 then + Result := 0x2be074cd + when 88 then + Result := 0x1e7a02e7 + when 89 then + Result := 0x11d10edd + when 90 then + Result := 0x05d92c68 + when 91 then + Result := 0xf50dbfb2 + when 92 then + Result := 0xdf9f1316 + when 93 then + Result := 0xcb52a684 + when 94 then + Result := 0xb8163e97 + when 95 then + Result := 0xa5d8f269 + when 96 then + Result := 0x948b0fcd + when 97 then + Result := 0x841e0215 + when 98 then + Result := 0x74843b1e + when 99 then + Result := 0x65b11e6e + when 100 then + Result := 0x5798ee23 + when 101 then + Result := 0x4a30b99b + when 102 then + Result := 0x3d6e4d94 + when 103 then + Result := 0x314825b0 + when 104 then + Result := 0x25b55f2e + when 105 then + Result := 0x1aadaccb + when 106 then + Result := 0x10294ba2 + when 107 then + Result := 0x10294ba2 + when 108 then + Result := 0xf91bd1b6 + when 109 then + Result := 0xe6d37b2a + when 110 then + Result := 0xd55cff6e + when 111 then + Result := 0xc4ad2db2 + when 112 then + Result := 0xb4b985cf + when 113 then + Result := 0xa5782bef + when 114 then + Result := 0x96dfdd2a + when 115 then + Result := 0x88e7e509 + when 116 then + Result := 0x7b8813d3 + when 117 then + Result := 0x6eb8b595 + when 118 then + Result := 0x627289db + when 119 then + Result := 0x56aebc07 + when 120 then + Result := 0x4b66dc33 + when 121 then + Result := 0x4094d8a3 + when 122 then + Result := 0x3632f7a5 + when 123 then + Result := 0x2c3bd1f0 + when 124 then + Result := 0x22aa4d5f + when 125 then + Result := 0x19799812 + when 126 then + Result := 0x10a523e5 + when 127 then + Result := 0x0828a237 + when 128 then + Result := 0x00000000 + when 129 then + Result := 0xf04ec452 + when 130 then + Result := 0xe136444a + when 131 then + Result := 0xd2af9589 + when 132 then + Result := 0xc4b42a83 + when 133 then + Result := 0xb73dccf5 + when 134 then + Result := 0xaa4698c5 + when 135 then + Result := 0x9dc8f729 + when 136 then + Result := 0x91bf9a30 + when 137 then + Result := 0x86257887 + when 138 then + Result := 0x7af5c98c + when 139 then + Result := 0x702c01a0 + when 140 then + Result := 0x65c3ceb1 + when 141 then + Result := 0x5bb91502 + when 142 then + Result := 0x5207ec23 + when 143 then + Result := 0x48ac9c19 + when 144 then + Result := 0x3fa39ab5 + when 145 then + Result := 0x36e98912 + when 146 then + Result := 0x2e7b3140 + when 147 then + Result := 0x2655840b + when 148 then + Result := 0x1e7596ea + when 149 then + Result := 0x16d8a20d + when 150 then + Result := 0x0f7bfe87 + when 151 then + Result := 0x085d2492 + when 152 then + Result := 0x0179a9f4 + when 153 then + Result := 0xf59e80eb + when 154 then + Result := 0xe8b768db + when 155 then + Result := 0xdc39d6d5 + when 156 then + Result := 0xd021c5d1 + when 157 then + Result := 0xc46b5e37 + when 158 then + Result := 0xb912f39c + when 159 then + Result := 0xae150294 + when 160 then + Result := 0xa36e2eb1 + when 161 then + Result := 0x991b4094 + when 162 then + Result := 0x8f19241e + when 163 then + Result := 0x8564e6b7 + when 164 then + Result := 0x7bfbb5b4 + when 165 then + Result := 0x72dadcc8 + when 166 then + Result := 0x69ffc498 + when 167 then + Result := 0x6167f154 + when 168 then + Result := 0x5911016e + when 169 then + Result := 0x50f8ac5f + when 170 then + Result := 0x491cc17c + when 171 then + Result := 0x417b26d8 + when 172 then + Result := 0x3a11d83b + when 173 then + Result := 0x32dee622 + when 174 then + Result := 0x2be074cd + when 175 then + Result := 0x2514bb58 + when 176 then + Result := 0x1e7a02e7 + when 177 then + Result := 0x180ea5d0 + when 178 then + Result := 0x11d10edd + when 179 then + Result := 0x0bbfb88e + when 180 then + Result := 0x05d92c68 + when 181 then + Result := 0x001c024c + when 182 then + Result := 0xf50dbfb2 + when 183 then + Result := 0xea30efa3 + when 184 then + Result := 0xdf9f1316 + when 185 then + Result := 0xd555c0c9 + when 186 then + Result := 0xcb52a684 + when 187 then + Result := 0xc193881f + when 188 then + Result := 0xb8163e97 + when 189 then + Result := 0xaed8b724 + when 190 then + Result := 0xa5d8f269 + when 191 then + Result := 0x9d15039d + when 192 then + Result := 0x948b0fcd + when 193 then + Result := 0x8c394d1d + when 194 then + Result := 0x841e0215 + when 195 then + Result := 0x7c3784f8 + when 196 then + Result := 0x74843b1e + when 197 then + Result := 0x6d02985d + when 198 then + Result := 0x65b11e6e + when 199 then + Result := 0x5e8e5c64 + when 200 then + Result := 0x5798ee23 + when 201 then + Result := 0x50cf7bde + when 202 then + Result := 0x4a30b99b + when 203 then + Result := 0x43bb66bd + when 204 then + Result := 0x3d6e4d94 + when 205 then + Result := 0x374842ee + when 206 then + Result := 0x314825b0 + when 207 then + Result := 0x2b6cde75 + when 208 then + Result := 0x25b55f2e + when 209 then + Result := 0x2020a2c5 + when 210 then + Result := 0x1aadaccb + when 211 then + Result := 0x155b891f + when 212 then + Result := 0x10294ba2 + when 213 then + Result := 0xb160fe9 + when 214 then + Result := 0x620f8f6 + when 215 then + Result := 0x14930ef + when 216 then + Result := 0xf91bd1b6 + when 217 then + Result := 0xefdcb0c7 + when 218 then + Result := 0xe6d37b2a + when 219 then + Result := 0xddfeb94a + when 220 then + Result := 0xd55cff6e + when 221 then + Result := 0xcceced50 + when 222 then + Result := 0xc4ad2db2 + when 223 then + Result := 0xbc9c75f9 + when 224 then + Result := 0xb4b985cf + when 225 then + Result := 0xad0326c2 + when 226 then + Result := 0xa5782bef + when 227 then + Result := 0x9e1771a9 + when 228 then + Result := 0x96dfdd2a + when 229 then + Result := 0x8fd05c41 + when 230 then + Result := 0x88e7e509 + when 231 then + Result := 0x8225759d + when 232 then + Result := 0x7b8813d3 + when 233 then + Result := 0x750eccf9 + when 234 then + Result := 0x6eb8b595 + when 235 then + Result := 0x6884e923 + when 236 then + Result := 0x627289db + when 237 then + Result := 0x5c80c07b + when 238 then + Result := 0x56aebc07 + when 239 then + Result := 0x50fbb19b + when 240 then + Result := 0x4b66dc33 + when 241 then + Result := 0x45ef7c7c + when 242 then + Result := 0x4094d8a3 + when 243 then + Result := 0x3b563c24 + when 244 then + Result := 0x3632f7a5 + when 245 then + Result := 0x312a60c3 + when 246 then + Result := 0x2c3bd1f0 + when 247 then + Result := 0x2766aa45 + when 248 then + Result := 0x22aa4d5f + when 249 then + Result := 0x1e06233c + when 250 then + Result := 0x19799812 + when 251 then + Result := 0x15041c33 + when 252 then + Result := 0x10a523e5 + when 253 then + Result := 0x0c5c2749 + when 254 then + Result := 0x0828a237 + when 255 then + Result := 0x040a1423 + when 256 then + Result := 0x00000000 + end + end +end diff --git a/library/crypto/eapml/facilities/powers.e b/library/crypto/eapml/facilities/powers.e new file mode 100644 index 00000000..29c69a7c --- /dev/null +++ b/library/crypto/eapml/facilities/powers.e @@ -0,0 +1,32 @@ +note + description: "Summary description for {POWERS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Giving a politician access to your wallet is like giving a dog access to your refrigerator. - Tim Barber" + +class + POWERS + +create + make + +feature + + make (digits_in_base_a: INTEGER; p_a: SPECIAL [NATURAL_32]; p_offset_a: INTEGER; n_a: INTEGER; base_a: INTEGER) + do + digits_in_base := digits_in_base_a + p := p_a + p_offset := p_offset_a + n := n_a + base := base_a + end + +feature + + digits_in_base: INTEGER + p: SPECIAL [NATURAL_32] + p_offset: INTEGER + n: INTEGER + base: INTEGER +end diff --git a/library/crypto/eapml/facilities/rand_lc_struct.e b/library/crypto/eapml/facilities/rand_lc_struct.e new file mode 100644 index 00000000..b7f129b3 --- /dev/null +++ b/library/crypto/eapml/facilities/rand_lc_struct.e @@ -0,0 +1,44 @@ +note + description: "Summary description for {RAND_LC_STRUCT}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Everyone wants to save the planet but no one wants to help Mom clean the dishes. - P.J. O'Rourke, in All the Trouble in the World " + +class + RAND_LC_STRUCT + +inherit + INTEGER_X_DIVISION + LIMB_MANIPULATION + +create + make + +feature + + make (m2exp_a: INTEGER; a_a: READABLE_INTEGER_X; seedn: INTEGER; c: NATURAL_32) + do + create cp.make_filled (0, 1) + m2exp := m2exp_a + create seed.make_limbs (bits_to_limbs (m2exp)) + seed.count := seedn + seed.item [0] := 1 + create a + fdiv_r_2exp (a, a_a, m2exp) + if a.count = 0 then + a.count := 1 + a.item [0] := 0 + end + cp [0] := c + cn := (c /= 0).to_integer + end + +feature + + seed: INTEGER_X + a: INTEGER_X + cn: INTEGER + cp: SPECIAL [NATURAL_32] + m2exp: INTEGER +end diff --git a/library/crypto/eapml/facilities/special_access.e b/library/crypto/eapml/facilities/special_access.e new file mode 100644 index 00000000..d47bf9a0 --- /dev/null +++ b/library/crypto/eapml/facilities/special_access.e @@ -0,0 +1,262 @@ +note + description: "Summary description for {NUMBER_ACCESS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "State-mandated compassion produces, not love for ones fellow man, but hatred and resentment. - Lizard" + +deferred class + SPECIAL_ACCESS + +inherit + LIMB_MANIPULATION + MP_BASES + SPECIAL_ARITHMETIC + SPECIAL_DIVISION + +feature + + dc_get_str (target_a: STRING_8; target_offset_a: INTEGER; len_a: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; powtab: SPECIAL [POWERS]; powtab_offset: INTEGER; tmp: SPECIAL [NATURAL_32]; tmp_offset: INTEGER): INTEGER + local + target: STRING_8 + len: INTEGER + pwp: SPECIAL [NATURAL_32] + pwp_offset: INTEGER + qp: SPECIAL [NATURAL_32] + qp_offset: INTEGER + rp: SPECIAL [NATURAL_32] + rp_offset: INTEGER + pwn: INTEGER + qn: INTEGER + target_offset: INTEGER + do + target := target_a + len := len_a + target_offset := target_offset_a + if op1_count < 15 then + if op1_count /= 0 then + target_offset := sb_get_str (target, target_offset, len, op1, op1_offset, op1_count, powtab, powtab_offset) + else + from + until + len /= 0 + loop + target [target_offset] := '%U' + target_offset := target_offset + 1 + len := len - 1 + end + end + else + pwp := powtab [powtab_offset].p + pwn := powtab [powtab_offset].n + if op1_count < pwn or (op1_count = pwn and cmp (op1, op1_offset, pwp, pwp_offset, op1_count) < 0) then + target_offset := dc_get_str (target, target_offset, len, op1, op1_offset, op1_count, powtab, powtab_offset - 1, tmp, tmp_offset) + else + qp := tmp + qp_offset := tmp_offset + rp := op1 + rp_offset := op1_offset + tdiv_qr (qp, qp_offset, rp, rp_offset, op1, op1_offset, op1_count, pwp, pwp_offset, pwn) + qn := op1_count - pwn + qn := qn + (qp [qp_offset + qn] /= 0).to_integer + if len /= 0 then + len := len - powtab [powtab_offset].digits_in_base + end + target_offset := dc_get_str (target, target_offset, len, qp, qp_offset, qn, powtab, powtab_offset - 1, tmp, tmp_offset + op1_count - pwn + 1) + target_offset := dc_get_str (target, target_offset, powtab [powtab_offset].digits_in_base, rp, rp_offset, pwn, powtab, powtab_offset - 1, tmp, tmp_offset) + end + end + Result := target_offset + end + + get_str (target: STRING_8; target_offset: INTEGER; base: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER): INTEGER + local + powtab_mem_ptr: SPECIAL [NATURAL_32] + powtab_mem_ptr_offset: INTEGER + big_base_l: NATURAL_32 + digits_in_base: INTEGER + powtab: SPECIAL [POWERS] + pi: INTEGER + n: INTEGER + t: INTEGER + p: SPECIAL [NATURAL_32] + p_offset: INTEGER + n1: NATURAL_32 + n0: NATURAL_32 + bits_per_digit: INTEGER + count: INTEGER + bit_pos: INTEGER + i: INTEGER + s: INTEGER + bits: INTEGER + do + if op1_count = 0 then + target [target_offset] := '%U' + Result := 1 + else + if pow2_p (base.to_natural_32) then + bits_per_digit := big_base (base).to_integer_32 + s := target_offset + n1 := op1 [op1_offset + op1_count - 1] + count := leading_zeros (n1) + bits := limb_bits * op1_count - count + count := bits \\ bits_per_digit + if count /= 0 then + bits := bits + bits_per_digit - count + end + bit_pos := bits - (op1_count - 1) * limb_bits + from + i := op1_count - 1 + until + i < 0 + loop + bit_pos := bit_pos - bits_per_digit + from + until + bit_pos < 0 + loop + target [s] := ((n1 |>> bit_pos).bit_and (((1).to_natural_32 |<< bits_per_digit) - 1)).to_character_8 + s := s + 1 + bit_pos := bit_pos - bits_per_digit + end + i := i - 1 + if i >= 0 then + n0 := (n1 |<< -bit_pos).bit_and (((1).to_natural_32 |<< bits_per_digit) - 1) + n1 := op1 [op1_offset + i] + bit_pos := bit_pos + limb_bits + target [s] := (n0.bit_or (n1 |>> bit_pos)).to_character_8 + s := s + 1 + end + end + Result := s - target_offset + else + if op1_count < 30 then + create powtab.make_empty (1) + create p.make_empty (0) + powtab.extend (create {POWERS}.make (0, p, 0, 0, base)) + Result := sb_get_str (target, target_offset, 0, op1, op1_offset, op1_count, powtab, 0) + else + create powtab_mem_ptr.make_filled (0, 2 * op1_count + 30) + big_base_l := big_base (base) + digits_in_base := chars_per_limb (base) + create powtab.make_empty (30) + create p.make_filled (0, 0) + powtab.extend (create {POWERS}.make (0, p, 0, 0, base)) + create p.make_filled (big_base_l, 1) + powtab.extend (create {POWERS}.make (digits_in_base, p, 0, 1, base)) + create p.make_filled (big_base_l, 1) + powtab.extend (create {POWERS}.make (digits_in_base, p, 0, 1, base)) + n := 1 + pi := 2 + create p.make_filled (big_base_l, 1) + p_offset := 0 + from + until + 2 * n > op1_count + loop + pi := pi + 1 + t := powtab_mem_ptr_offset + powtab_mem_ptr_offset := powtab_mem_ptr_offset + 2 * n + sqr_n (powtab_mem_ptr, t, p, p_offset, n) + n := n * 2 + n := n - (powtab_mem_ptr [t + n - 1] = 0).to_integer + digits_in_base := digits_in_base * 2 + powtab_mem_ptr_offset := t + powtab.extend (create {POWERS}.make (digits_in_base, p, 0, n, base)) + end + end + end + end + end + + sb_get_str (target: STRING_8; target_offset_a: INTEGER; len_a: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count_a: INTEGER; powtab: SPECIAL [POWERS]; powtab_offset: INTEGER): INTEGER + local + rl: CELL [NATURAL_32] + ul: CELL [NATURAL_32] + s: INTEGER + base: INTEGER + l: INTEGER + buf: SPECIAL [NATURAL_8] + buf_offset: INTEGER + rp: SPECIAL [NATURAL_32] + rp_offset: INTEGER + buff_alloc: INTEGER + op1_count: INTEGER + i: INTEGER + frac: CELL [NATURAL_32] + digit: CELL [NATURAL_32] + junk: NATURAL_32 + chars_per_limb_l: INTEGER + big_base_l: NATURAL_32 + big_base_inverted_l: NATURAL_32 + normalization_steps: INTEGER + target_offset: INTEGER + len: INTEGER + do + create digit.put (0) + create frac.put (0) + create ul.put (0) + create rl.put (0) + len := len_a + target_offset := target_offset_a + op1_count := op1_count_a + buff_alloc := 30 * 8 * 4 * 7 // 11 + create buf.make_filled (0, buff_alloc) + create rp.make_filled (0, 30) + base := powtab [powtab_offset].base + chars_per_limb_l := chars_per_limb (base) + big_base_l := big_base (base) + big_base_inverted_l := big_base_inverted (base) + normalization_steps := leading_zeros (big_base_l) + rp.copy_data (op1, op1_offset, rp_offset + 1, op1_count) + s := buf_offset + buff_alloc + from + until + op1_count <= 1 + loop + junk := preinv_divrem_1 (rp, rp_offset, 1, rp, rp_offset + 1, op1_count, big_base_l, big_base_inverted_l, normalization_steps) + op1_count := op1_count - (rp [rp_offset + op1_count] = 0).to_integer + frac.put (rp [rp_offset] + 1) + s := s - chars_per_limb_l + i := chars_per_limb_l + from + until + i = 0 + loop + umul_ppmm (digit, frac, frac.item, base.to_natural_32) + buf [s] := digit.item.to_natural_8 + s := s + 1 + i := i - 1 + end + s := s - chars_per_limb_l + end + ul.put (rp [rp_offset + 1]) + from + until + ul.item = 0 + loop + udiv_qrnd_unnorm (ul, rl, ul.item, base.to_natural_32) + s := s - 1 + buf [s] := rl.item.to_natural_8 + end + l := buf_offset + buff_alloc - s + from + until + l >= len + loop + target [target_offset] := '%U' + target_offset := target_offset + 1 + len := len - 1 + end + from + until + l = 0 + loop + target [target_offset] := buf [s].to_character_8 + s := s + 1 + target_offset := target_offset + 1 + l := l - 1 + end + Result := target_offset - target_offset_a + end +end diff --git a/library/crypto/eapml/facilities/special_arithmetic.e b/library/crypto/eapml/facilities/special_arithmetic.e new file mode 100644 index 00000000..430c4f1e --- /dev/null +++ b/library/crypto/eapml/facilities/special_arithmetic.e @@ -0,0 +1,1022 @@ +note + description: "Summary description for {NUMBER_ARITHMETIC}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Dependence leads to subservience. - Thomas Jefferson" + +deferred class + SPECIAL_ARITHMETIC + +inherit + LIMB_BIT_SCANNING + LIMB_MANIPULATION + SPECIAL_LOGIC + +feature + + add (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; op2_count: INTEGER_32; carry: CELL [NATURAL_32]) + require + op2_count >= 0 + op1_count >= op2_count + op2_count = 0 or target.valid_index (target_offset) + op2_count = 0 or target.valid_index (target_offset + op1_count - 1) + op2_count = 0 or op1.valid_index (op1_offset) + op2_count = 0 or op1.valid_index (op1_offset + op1_count - 1) + op2_count = 0 or op2.valid_index (op2_offset) + op2_count = 0 or op2.valid_index (op2_offset + op2_count - 1) + local + i: INTEGER_32 + x: NATURAL_32 + add_carry: NATURAL_32 + j: INTEGER_32 + done: BOOLEAN + do + i := op2_count + add_n (target, target_offset, op1, op1_offset, op2, op2_offset, i, carry) + add_carry := carry.item + if add_carry /= 0 then + from + x := 0 + until + done or x /= 0 + loop + if i >= op1_count then + carry.put (1) + done := True + else + x := op1 [op1_offset + i] + x := x + 1 + target [target_offset + i] := x + i := i + 1 + end + end + end + if not done then + if target /= op1 then + from + j := i + until + j >= op1_count + loop + target [target_offset + j] := op1 [op1_offset + j] + j := j + 1 + end + end + carry.put (0) + end + end + + add_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; size: INTEGER_32; op2: NATURAL_32; carry: CELL [NATURAL_32]) + -- Adds number in SPECIAL `op1' at `op1_offset' of length `size' to the single limb `op2' storing the result in `target' at `target_offset' and carry in `carry' + local + i: INTEGER_32 + r: NATURAL_32 + do + r := op1 [op1_offset] + op2 + target [target_offset] := r + if r < op2 then + from + i := 1 + r := 0 + until + i >= size or r /= 0 + loop + r := op1 [op1_offset + i] + 1 + target [target_offset + i] := r + i := i + 1 + end + target.copy_data (op1, op1_offset + i, target_offset + i, size - i) + carry.put ((i = size and r = 0).to_integer.to_natural_32) + else + if target /= op1 then + target.copy_data (op1, op1_offset + 1, target_offset + 1, size - 1) + end + carry.put (0) + end + ensure + carry.item = 0 or carry.item = 1 + end + + add_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; n: INTEGER_32; carry: CELL [NATURAL_32]) + -- Add two numbers in SPECIAL `op1' at `op1_offset' and `op2' at `op2_offset' both of length `n' putting result in `target' at `target_offset' and carry in `carry' + require + n >= 0 + n = 0 or op1.valid_index (op1_offset) + n = 0 or op1.valid_index (op1_offset + n - 1) + n = 0 or op2.valid_index (op2_offset) + n = 0 or op2.valid_index (op2_offset + n - 1) + n = 0 or target.valid_index (target_offset) + n = 0 or target.valid_index (target_offset + n - 1) + local + ul: NATURAL_32 + vl: NATURAL_32 + sl: NATURAL_32 + rl: NATURAL_32 + cy1: NATURAL_32 + cy2: NATURAL_32 + cursor: INTEGER_32 + carry_l: NATURAL_32 + do + from + cursor := 0 + until + cursor = n + loop + ul := op1 [cursor + op1_offset] + vl := op2 [cursor + op2_offset] + sl := ul + vl + cy1 := (sl < ul).to_integer.to_natural_32 + rl := sl + carry_l + cy2 := (rl < sl).to_integer.to_natural_32 + carry_l := cy1.bit_or (cy2) + target [cursor + target_offset] := rl + cursor := cursor + 1 + variant + n - cursor + 1 + end + carry.put (carry_l) + end + + addmul_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; vl: NATURAL_32; carry: CELL [NATURAL_32]) + require + n >= 0 + local + ul: NATURAL_32 + hpl: CELL [NATURAL_32] + lpl: CELL [NATURAL_32] + rl: NATURAL_32 + cursor: INTEGER_32 + carry_l: NATURAL_32 + do + create hpl.put (0) + create lpl.put (0) + from + cursor := 0 + until + n - cursor = 0 + loop + ul := op1 [op1_offset + cursor] + umul_ppmm (hpl, lpl, ul, vl) + lpl.put (lpl.item + carry_l) + carry_l := (lpl.item < carry_l).to_integer.to_natural_32 + hpl.item + rl := target [target_offset + cursor] + lpl.put (rl + lpl.item) + carry_l := carry_l + (lpl.item < rl).to_integer.to_natural_32 + target [target_offset + cursor] := lpl.item + cursor := cursor + 1 + variant + n - cursor + 1 + end + carry.put (carry_l) + end + + decr_u (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; decr: NATURAL_32) + local + x: NATURAL_32 + cursor: INTEGER_32 + do + cursor := target_offset + x := target [target_offset] + target [target_offset] := x - decr + if x < decr then + from + cursor := target_offset + 1 + x := 0 + until + x /= 0 + loop + x := target [cursor] + x := x - 1 + target [cursor] := x + cursor := cursor + 1 + end + end + end + + incr_u (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; incr: NATURAL_32) + local + x: NATURAL_32 + cursor: INTEGER_32 + do + x := target [target_offset] + incr + target [target_offset] := x + if x < incr then + from + cursor := target_offset + 1 + x := 0 + until + x /= 0 + loop + x := target [cursor] + x := x + 1 + target [cursor] := x + cursor := cursor + 1 + end + end + end + + mul (target: SPECIAL [NATURAL_32]; target_offset_a: INTEGER_32; op1_a: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER_32; op1_count_a: INTEGER_32; op2_a: SPECIAL [NATURAL_32]; op2_offset_a: INTEGER_32; op2_count_a: INTEGER_32; carry: CELL [NATURAL_32]) + require + target.valid_index (target_offset_a) + target.valid_index (target_offset_a + op2_count_a - 1) + op1_a.valid_index (op1_offset_a) + op1_a.valid_index (op1_offset_a + op2_count_a - 1) + op1_count_a >= op2_count_a + op2_count_a >= 1 + local + l: INTEGER_32 + t: NATURAL_32 + ws: SPECIAL [NATURAL_32] + op1: SPECIAL [NATURAL_32] + op2: SPECIAL [NATURAL_32] + int_temp: INTEGER_32 + special_temp: SPECIAL [NATURAL_32] + op1_count: INTEGER_32 + op2_count: INTEGER_32 + op1_offset: INTEGER_32 + op2_offset: INTEGER_32 + target_offset: INTEGER_32 + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + cy: NATURAL_32 + c: NATURAL_32 + do + op1 := op1_a + op2 := op2_a + op1_count := op1_count_a + op2_count := op2_count_a + op1_offset := op1_offset_a + op2_offset := op2_offset_a + target_offset := target_offset_a + if op1_count = op2_count then + if op1 = op2 and op1_offset = op2_offset then + sqr_n (target, target_offset, op1, op1_offset, op1_count) + carry.put (target [target_offset + 2 * op1_count - 1]) + else + mul_n (target, target_offset, op1, op1_offset, op2, op2_offset, op1_count) + carry.put (target [target_offset + 2 * op1_count - 1]) + end + else + if op2_count < 32 then + if op1_count <= 500 then + mul_basecase (target, target_offset, op1, op1_offset, op1_count, op2, op2_offset, op2_count) + else + create tp.make_filled (0, 32) + mul_basecase (target, target_offset, op1, op1_offset, 500, op2, op2_offset, op2_count) + target_offset := target_offset + 500 + tp.copy_data (target, target_offset, tp_offset, op2_count) + op1_offset := op1_offset + 500 + op1_count := op1_count - 500 + from + until + op1_count <= 500 + loop + mul_basecase (target, target_offset, op1, op1_offset, 500, op2, op2_offset, op2_count) + add_n (target, target_offset, target, target_offset, tp, tp_offset, op2_count, carry) + cy := carry.item + incr_u (target, target_offset + op2_count, cy) + target_offset := target_offset + 500 + tp.copy_data (target, target_offset, tp_offset, op2_count) + op1_offset := op1_offset + 500 + op1_count := op1_count - 500 + end + if op1_count > op2_count then + mul_basecase (target, target_offset, op1, op1_offset, op1_count, op2, op2_offset, op2_count) + else + mul_basecase (target, target_offset, op2, op2_offset, op2_count, op1, op1_offset, op1_count) + end + add_n (target, target_offset, target, target_offset, tp, tp_offset, op2_count, carry) + cy := carry.item + incr_u (target, target_offset + op2_count, cy) + end + carry.put (target [target_offset + op1_count + op2_count - 1]) + else + mul_n (target, target_offset, op1, op1_offset, op2, op2_offset, op2_count) + if op1_count /= op2_count then + target_offset := target_offset + op2_count + l := op2_count + op1_offset := op1_offset + op2_count + op1_count := op1_count - op2_count + if op1_count < op2_count then + special_temp := op1 + op1 := op2 + op2 := special_temp + int_temp := op1_offset + op1_offset := op2_offset + op2_offset := int_temp + int_temp := op1_count + op1_count := op2_count + op2_count := int_temp + end + if op2_count >= 32 then + create ws.make_filled (0, op2_count + op2_count) + else + create ws.make_filled (0, op1_count + op2_count) + end + from + t := 0 + until + op2_count < 32 + loop + mul_n (ws, 0, op1, op1_offset, op2, op2_offset, op2_count) + if l <= 2 * op2_count then + add_n (target, target_offset, target, target_offset, ws, 0, 1, carry) + t := t + carry.item + if l /= 2 * op2_count then + add_1 (target, target_offset + 1, ws, 1, 2 * op2_count - 1, t, carry) + t := carry.item + l := 2 * op2_count + end + else + add_n (target, target_offset, target, target_offset, ws, 0, 2 * op2_count, carry) + c := carry.item + add_1 (target, target_offset + 2 * op2_count, target, target_offset + 2 * op2_count, 1 - 2 * op2_count, c, carry) + t := t + carry.item + end + target_offset := target_offset + op2_count + l := l - op2_count + op1_offset := op1_offset + op2_count + op1_count := op1_count - op2_count + if op1_count < op2_count then + special_temp := op1 + op1 := op2 + op2 := special_temp + int_temp := op1_count + op1_count := op2_count + op2_count := int_temp + int_temp := op1_offset + op1_offset := op2_offset + op2_offset := int_temp + end + end + if op2_count /= 0 then + mul_basecase (ws, 0, op1, op1_offset, op1_count, op2, op2_offset, op2_count) + if l <= op1_count + op2_count then + add_n (target, target_offset, target, target_offset, ws, 0, l, carry) + t := t + carry.item + if l /= op1_count + op2_count then + add_1 (target, target_offset + l, ws, l, op1_count + op2_count - l, t, carry) + t := carry.item + else + add_n (target, target_offset, target, target_offset, ws, 0, op1_count + op2_count, carry) + c := carry.item + add_1 (target, target_offset + op1_count + op2_count, target, target_offset + op1_count + op2_count, l - op1_count - op2_count, c, carry) + t := t + carry.item + end + end + end + end + carry.put (target [op1_count + op2_count - 1]) + end + end + end + + mul_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; vl: NATURAL_32; carry: CELL [NATURAL_32]) + require + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + n - 1) + target.valid_index (target_offset) + target.valid_index (target_offset + n - 1) + local + ul: NATURAL_32 + hpl: CELL [NATURAL_32] + lpl: CELL [NATURAL_32] + cursor: INTEGER_32 + carry_l: NATURAL_32 + do + create hpl.put (0) + create lpl.put (0) + from + until + n = cursor + loop + ul := op1 [op1_offset + cursor] + umul_ppmm (hpl, lpl, ul, vl) + lpl.put (lpl.item + carry_l) + carry_l := (lpl.item < carry_l).to_integer.to_natural_32 + carry_l := carry_l + hpl.item + target [target_offset + cursor] := lpl.item + cursor := cursor + 1 + end + carry.put (carry_l) + end + + mul_basecase (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; op2_count: INTEGER_32) + require + op2_count >= 1 + op1_count >= op2_count + target.valid_index (target_offset) + target.valid_index (target_offset + op1_count - 1) + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + op1_count - 1) + local + cursor: INTEGER_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + mul_1 (target, target_offset, op1, op1_offset, op1_count, op2 [op2_offset], carry) + target [target_offset + op1_count] := carry.item + cursor := 1 + from + until + op2_count = cursor + loop + addmul_1 (target, target_offset + cursor, op1, op1_offset, op1_count, op2 [op2_offset + cursor], carry) + target [target_offset + op1_count + cursor] := carry.item + cursor := cursor + 1 + end + end + + mul_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; n: INTEGER_32) + require + n >= 1 + target.valid_index (target_offset) + target.valid_index (target_offset + n - 1) + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + n - 1) + local + ws: SPECIAL [NATURAL_32] + do + if n < 32 then + mul_basecase (target, target_offset, op1, op1_offset, n, op2, op2_offset, n) + else + create ws.make_filled (0, 2 * n + 2 * 32) + kara_mul_n (target, target_offset, op1, op1_offset, op2, op2_offset, n, ws, 0) + end + end + + kara_mul_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; a: SPECIAL [NATURAL_32]; a_offset: INTEGER_32; b: SPECIAL [NATURAL_32]; b_offset: INTEGER_32; n: INTEGER_32; ws: SPECIAL [NATURAL_32]; w_offset: INTEGER_32) + require + n >= 2 + local + w: NATURAL_32 + w0: NATURAL_32 + w1: NATURAL_32 + c: NATURAL_32 + n2: INTEGER_32 + x: INTEGER_32 + y: INTEGER_32 + i: INTEGER_32 + sign: INTEGER_32 + n1: INTEGER_32 + n3: INTEGER_32 + nm1: INTEGER_32 + junk: NATURAL_32 + xlimb: NATURAL_32 + cursor: INTEGER_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + n2 := n |>> 1 + if n.bit_and (0x1) /= 0 then + n3 := n - n2 + sign := 0 + w := a [a_offset + n2] + if w /= 0 then + sub_n (target, target_offset, a, a_offset, a, a_offset + n3, n2, carry) + w := w - carry.item + else + i := n2 + from + w0 := w1 + until + w0 /= w1 or else i = 0 + loop + i := i - 1 + w0 := a [a_offset + i] + w1 := a [a_offset + n3 + i] + end + if w0 < w1 then + x := a_offset + n3 + y := a_offset + sign := -1 + else + x := a_offset + y := a_offset + n3 + end + sub_n (target, target_offset, a, x, a, y, n2, carry) + junk := carry.item + end + target [target_offset + n2] := w + w := b [b_offset + n2] + if w /= 0 then + sub_n (target, target_offset + n3, b, b_offset, b, b_offset + n3, n2, carry) + w := w - carry.item + else + i := n2 + from + w0 := w1 + until + w0 /= w1 or else i = 0 + loop + i := i - 1 + w0 := b [b_offset + i] + w1 := b [b_offset + n3 + i] + end + if w0 < w1 then + x := b_offset + n3 + y := b_offset + sign := sign.bit_not + else + x := b_offset + y := b_offset + n3 + end + sub_n (target, target_offset + n3, b, x, b, y, n2, carry) + junk := carry.item + end + target [target_offset + n] := w + n1 := n + 1 + if n2 < 32 then + if n3 < 32 then + mul_basecase (ws, w_offset, target, target_offset, n3, target, target_offset + n3, n3) + mul_basecase (target, target_offset, a, a_offset, n3, b, b_offset, n3) + else + kara_mul_n (ws, w_offset, target, target_offset, target, target_offset + n3, n3, ws, w_offset + n1) + kara_mul_n (target, target_offset, a, a_offset, b, b_offset, n3, ws, w_offset + n1) + end + mul_basecase (target, target_offset + n1, a, a_offset + n3, n2, b, b_offset + n3, n2) + else + kara_mul_n (ws, w_offset, target, target_offset, target, target_offset + n3, n3, ws, w_offset + n1) + kara_mul_n (target, target_offset, a, a_offset, b, b_offset, n3, ws, w_offset + n1) + kara_mul_n (target, target_offset + n1, a, a_offset + n3, b, b_offset + n3, n2, ws, w_offset + n1) + end + nm1 := n - 1 + if sign /= 0 then + add_n (ws, w_offset, target, target_offset, ws, w_offset, n1, carry) + junk := carry.item + add_n (ws, w_offset, target, target_offset + n1, ws, w_offset, nm1, carry) + c := carry.item + if c /= 0 then + xlimb := ws [w_offset + nm1] + 1 + ws [w_offset + nm1] := xlimb + if xlimb = 0 then + ws [w_offset + n] := ws [w_offset + n] + 1 + end + end + else + sub_n (ws, w_offset, target, target_offset, ws, w_offset, n1, carry) + junk := carry.item + add_n (ws, w_offset, target, target_offset + n1, ws, w_offset, nm1, carry) + c := carry.item + if c /= 0 then + xlimb := ws [w_offset + nm1] + 1 + ws [w_offset + nm1] := xlimb + if xlimb = 0 then + ws [w_offset + n] := ws [w_offset + n] + 1 + end + end + end + add_n (target, target_offset + n3, target, target_offset + n3, ws, w_offset, n1, carry) + xlimb := carry.item + if xlimb /= 0 then + xlimb := target [target_offset + n1 + n3] + 1 + target [target_offset + n1 + n3] := xlimb + from + cursor := 1 + until + xlimb /= 0 + loop + xlimb := target [target_offset + n1 + n3 + cursor] + 1 + target [target_offset + n1 + n3 + cursor] := xlimb + cursor := cursor + 1 + end + end + else + i := n2 + from + w0 := w1 + until + w0 /= w1 or i = 0 + loop + i := i - 1 + w0 := a [a_offset + i] + w1 := a [a_offset + n2 + i] + end + sign := 0 + if w0 < w1 then + x := a_offset + n2 + y := a_offset + sign := -1 + else + x := a_offset + y := a_offset + n2 + end + sub_n (target, target_offset, a, x, a, y, n2, carry) + junk := carry.item + i := n2 + from + w0 := w1 + until + w0 /= w1 or i = 0 + loop + i := i - 1 + w0 := b [b_offset + i] + w1 := b [b_offset + n2 + i] + end + if w0 < w1 then + x := b_offset + n2 + y := b_offset + sign := sign.bit_not + else + x := b_offset + y := b_offset + n2 + end + sub_n (target, target_offset + n2, b, x, b, y, n2, carry) + junk := carry.item + if n2 < 32 then + mul_basecase (ws, w_offset, target, target_offset, n2, target, target_offset + n2, n2) + mul_basecase (target, target_offset, a, a_offset, n2, b, b_offset, n2) + mul_basecase (target, target_offset + n, a, a_offset + n2, n2, b, b_offset + n2, n2) + else + kara_mul_n (ws, w_offset, target, target_offset, target, target_offset + n2, n2, ws, w_offset + n) + kara_mul_n (target, target_offset, a, a_offset, b, b_offset, n2, ws, w_offset + n) + kara_mul_n (target, target_offset + n, a, a_offset + n2, b, b_offset + n2, n2, ws, w_offset + n) + end + if sign /= 0 then + add_n (ws, w_offset, target, target_offset, ws, w_offset, n, carry) + w := carry.item + add_n (ws, w_offset, target, target_offset + n, ws, w_offset, n, carry) + w := w + carry.item + else + sub_n (ws, w_offset, target, target_offset, ws, w_offset, n, carry) + w := (0).to_natural_32 - carry.item + add_n (ws, w_offset, target, target_offset + n, ws, w_offset, n, carry) + w := w + carry.item + end + add_n (target, target_offset + n2, target, target_offset + n2, ws, w_offset, n, carry) + w := w + carry.item + xlimb := target [target_offset + n2 + n] + w + target [target_offset + n2 + n] := xlimb + if xlimb < w then + from + xlimb := 0 + cursor := 1 + until + xlimb /= 0 + loop + xlimb := target [target_offset + n2 + n + cursor] + 1 + target [target_offset + n2 + n + cursor] := xlimb + cursor := cursor + 1 + end + end + end + end + + kara_sqr_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; ws: SPECIAL [NATURAL_32]; ws_offset: INTEGER) + require + op1_count >= 2 + local + w: NATURAL_32 + w0: NATURAL_32 + w1: NATURAL_32 + c: NATURAL_32 + n2: INTEGER + x: SPECIAL [NATURAL_32] + x_offset: INTEGER + y: SPECIAL [NATURAL_32] + y_offset: INTEGER + i: INTEGER + n1: INTEGER + n3: INTEGER + nm1: INTEGER + junk: NATURAL_32 + xlimb: NATURAL + carry: CELL [NATURAL_32] + do + create carry.put (0) + n2 := op1_count |>> 1 + if op1_count.bit_test (0) then + n3 := op1_count - n2 + w := op1 [op1_offset + n2] + if w /= 0 then + sub_n (target, target_offset, op1, op1_offset, op1, op1_offset + n3, n2, carry) + w := w - carry.item + else + i := n2 + from + w0 := w1 + check i /= 0 end + until + w0 /= w1 or i = 0 + loop + i := i - 1 + w0 := op1 [op1_offset + i] + w1 := op1 [op1_offset + n3 + i] + end + if w0 < w1 then + x := op1 + x_offset := op1_offset + n3 + y := op1 + y_offset := op1_offset + else + x := op1 + x_offset := op1_offset + y := op1 + y_offset := op1_offset + n3 + end + sub_n (target, target_offset, x, x_offset, y, y_offset, n2, carry) + junk := carry.item + end + target [target_offset + n2] := w + n1 := op1_count + 1 + if n3 < 64 then + sqr_basecase (ws, ws_offset, target, target_offset, n3) + sqr_basecase (target, target_offset, op1, op1_offset, n3) + else + kara_sqr_n (ws, ws_offset, target, target_offset, n3, ws, ws_offset + n1) + kara_sqr_n (target, target_offset, op1, op1_offset, n3, ws, ws_offset + n1) + end + if n2 < 64 then + sqr_basecase (target, target_offset + n1, op1, op1_offset + n3, n2) + else + kara_sqr_n (target, target_offset + n1, op1, op1_offset + n3, n3, ws, ws_offset + n1) + end + nm1 := op1_count - 1 + sub_n (ws, ws_offset, target, target_offset, ws, ws_offset, n1, carry) + junk := carry.item + add_n (ws, ws_offset, target, target_offset + n1, ws, ws_offset, nm1, carry) + c := carry.item + if c /= 0 then + xlimb := ws [ws_offset + nm1] + ws [ws_offset + nm1] := xlimb + if xlimb = 0 then + ws [ws_offset + op1_count] := ws [ws_offset + op1_count] + 1 + end + end + add_n (target, target_offset + n3, target, target_offset + n3, ws, ws_offset, n1, carry) + if carry.item /= 0 then + incr_u (target, target_offset + n1 + n3, 1) + end + else + i := n2 + from + w0 := w1 + check i /= 0 end + until + w0 /= w1 or i = 0 + loop + i := i - 1 + w0 := op1 [op1_offset + i] + w1 := op1 [op1_offset + n2 + i] + end + if w0 < w1 then + x := op1 + x_offset := op1_offset + n2 + y := op1 + y_offset := op1_offset + else + x := op1 + x_offset := op1_offset + y := op1 + y_offset := op1_offset + n2 + end + sub_n (target, target_offset, x, x_offset, y, y_offset, n2, carry) + junk := carry.item + if n2 < 64 then + sqr_basecase (ws, ws_offset, target, target_offset, n2) + sqr_basecase (target, target_offset, op1, op1_offset, n2) + sqr_basecase (target, target_offset + op1_count, op1, op1_offset + n2, n2) + else + kara_sqr_n (ws, ws_offset, target, target_offset, n2, ws, ws_offset + op1_count) + kara_sqr_n (target, target_offset, op1, op1_offset, n2, ws, ws_offset + op1_count) + kara_sqr_n (target, target_offset + op1_count, op1, op1_offset + n2, n2, ws, ws_offset + op1_count) + end + sub_n (ws, ws_offset, target, target_offset, ws, ws_offset, op1_count, carry) + w := 0 - carry.item + add_n (ws, ws_offset, target, target_offset + op1_count, ws, ws_offset, op1_count, carry) + w := w + carry.item + add_n (target, target_offset + n2, target, target_offset + n2, ws, ws_offset, op1_count, carry) + w := w + carry.item + incr_u (target, target_offset + n2 + op1_count, w) + end + end + + sqr_basecase (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER) + require + op1_count >= 1 + local + i: INTEGER + ul: NATURAL_32 + lpl: CELL [NATURAL_32] + temp: CELL [NATURAL_32] + tarr: SPECIAL [NATURAL_32] + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + cy: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + create lpl.put (0) + create temp.put (0) + ul := op1 [op1_offset] + umul_ppmm (temp, lpl, ul, ul) + target [target_offset + 1] := temp.item + target [target_offset] := lpl.item + if op1_count > 1 then + create tarr.make_filled (0, 128) + tp := tarr + mul_1 (tp, tp_offset, op1, op1_offset + 1, op1_count - 1, op1 [op1_offset], carry) + cy := carry.item + tp [tp_offset + op1_count - 1] := cy + from + i := 2 + until + i >= op1_count + loop + addmul_1 (tp, tp_offset + 2 * i - 2, op1, op1_offset + i, op1_count - i, op1 [op1_offset + i - 1], carry) + cy := carry.item + tp [tp_offset + op1_count + i - 2] := cy + i := i + 1 + end + sqr_diagonal (target, target_offset + 2, op1, op1_offset + 1, op1_count - 1) + lshift (tp, tp_offset, tp, tp_offset, 2 * op1_count - 2, 1, carry) + cy := carry.item + add_n (target, target_offset + 1, target, target_offset + 1, tp, tp_offset, 2 * op1_count - 2, carry) + cy := cy + carry.item + target [target_offset + 2 * op1_count - 1] := target [target_offset + 2 * op1_count - 1] + cy + end + end + + sqr_diagonal (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER) + local + i: INTEGER + ul: NATURAL_32 + lpl: CELL [NATURAL_32] + temp: CELL [NATURAL_32] + do + create lpl.put (0) + create temp.put (0) + from + i := 0 + until + i >= op1_count + loop + ul := op1 [op1_offset + i] + umul_ppmm (temp, lpl, ul, ul) + target [target_offset + 2 * i + 1] := temp.item + target [target_offset + 2 * i] := lpl.item + i := i + 1 + end + end + + sqr_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER) + require + op1_count >= 1 + local + ws: SPECIAL [NATURAL_32] + ws_offset: INTEGER + do + if op1_count < 64 then + sqr_basecase (target, target_offset, op1, op1_offset, op1_count) + else + create ws.make_filled (0, 2 * op1_count + 2 * 32) + kara_sqr_n (target, target_offset, op1, op1_offset, op1_count, ws, ws_offset) + end + end + + sub (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; op2_count: INTEGER_32; carry: CELL [NATURAL_32]) + local + i: INTEGER_32 + j: INTEGER_32 + x: NATURAL_32 + subtract_borrow: NATURAL_32 + done: BOOLEAN + do + i := op2_count + sub_n (target, target_offset, op1, op1_offset, op2, op2_offset, i, carry) + subtract_borrow := carry.item + if subtract_borrow /= 0 then + from + x := 0 + until + done or x /= 0 + loop + if i >= op1_count then + carry.put (1) + done := True + else + x := op1 [op1_offset + i] + target [target_offset + i] := x - 1 + i := i + 1 + end + end + end + if not done then + if target /= op1 then + from + j := i + until + j >= op1_count + loop + target [target_offset + j] := op1 [op1_offset + j] + j := j + 1 + end + end + carry.put (0) + end + end + + sub_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: NATURAL_32; carry: CELL [NATURAL_32]) + require + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + op1_count - 1) + target.valid_index (target_offset) + target.valid_index (target_offset + op1_count - 1) + local + i: INTEGER_32 + x: NATURAL_32 + r: NATURAL_32 + do + x := op1 [op1_offset] + r := x - op2 + target [target_offset] := r + if x < op2 then + carry.put (1) + from + i := 1 + until + i >= op1_count + loop + x := op1 [op1_offset + i] + r := x - 1 + target [target_offset + i] := r + i := i + 1 + if not (x < 1) then + if op1 /= target then + target.copy_data (op1, op1_offset + i, target_offset + i, op1_count - i) + end + carry.put (0) + i := op1_count + end + end + else + if op1 /= target then + target.copy_data (op1, op1_offset + 1, target_offset + 1, op1_count - 1) + end + carry.put (0) + end + end + + sub_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; n: INTEGER_32; carry: CELL [NATURAL_32]) + local + ul: NATURAL_32 + vl: NATURAL_32 + sl: NATURAL_32 + rl: NATURAL_32 + cy1: NATURAL_32 + cy2: NATURAL_32 + cursor: INTEGER_32 + carry_l: NATURAL_32 + do + from + cursor := 0 + until + cursor = n + loop + ul := op1 [op1_offset + cursor] + vl := op2 [op2_offset + cursor] + sl := ul - vl + cy1 := (sl > ul).to_integer.to_natural_32 + rl := sl - carry_l + cy2 := (rl > sl).to_integer.to_natural_32 + carry_l := cy1.bit_or (cy2) + target [target_offset + cursor] := rl + cursor := cursor + 1 + end + carry.put (carry_l) + end + + submul_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; op2: NATURAL_32; carry: CELL [NATURAL_32]) + require + target.valid_index (target_offset) + target.valid_index (target_offset + n - 1) + n >= 1 + local + ul: NATURAL_32 + hpl: CELL [NATURAL_32] + lpl: CELL [NATURAL_32] + rl: NATURAL_32 + cursor: INTEGER_32 + carry_l: NATURAL_32 + do + create hpl.put (0) + create lpl.put (0) + from + cursor := 0 + until + cursor >= n + loop + ul := op1 [op1_offset + cursor] + umul_ppmm (hpl, lpl, ul, op2) + lpl.put (lpl.item + carry_l) + carry_l := (lpl.item < carry_l).to_integer.to_natural_32 + hpl.item + rl := target [target_offset + cursor] + lpl.put (rl - lpl.item) + carry_l := carry_l + (lpl.item > rl).to_integer.to_natural_32 + target [target_offset + cursor] := lpl.item + cursor := cursor + 1 + end + carry.put (carry_l) + end +end diff --git a/library/crypto/eapml/facilities/special_assignment.e b/library/crypto/eapml/facilities/special_assignment.e new file mode 100644 index 00000000..95430191 --- /dev/null +++ b/library/crypto/eapml/facilities/special_assignment.e @@ -0,0 +1,159 @@ +note + description: "Summary description for {NUMBER_ASSIGNMENT}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Concentrated political power is the most dangerous thing on earth. - Rudolph Rummel" + +deferred class + SPECIAL_ASSIGNMENT + +inherit + MP_BASES + LIMB_MANIPULATION + SPECIAL_ARITHMETIC + +feature + + set_str (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; str: SPECIAL [NATURAL_8]; str_offset_a: INTEGER; str_len: INTEGER; base: INTEGER): INTEGER + require + base >= 2 +-- str_len >= 1 + local + str_offset: INTEGER + size: INTEGER + big_base_l: NATURAL_32 + chars_per_limb_l: INTEGER + res_digit: NATURAL_32 + s: INTEGER + next_bitpos: INTEGER + bits_per_indigit: INTEGER + inp_digit: NATURAL_8 + i: INTEGER + j: INTEGER + cy_limb: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + str_offset := str_offset_a + big_base_l := big_base (base) + chars_per_limb_l := chars_per_limb (base) + size := 0 + if pow2_p (base.to_natural_32) then + bits_per_indigit := big_base_l.to_integer_32 + res_digit := 0 + next_bitpos := 0 + from + s := str_offset + str_len - 1 + until + s < str_offset + loop + inp_digit := str [s] + res_digit := res_digit.bit_or (inp_digit.to_natural_32 |<< next_bitpos) + next_bitpos := next_bitpos + bits_per_indigit + if next_bitpos >= limb_bits then + target [target_offset + size] := res_digit + size := size + 1 + next_bitpos := next_bitpos - limb_bits + res_digit := inp_digit |>> (bits_per_indigit - next_bitpos) + end + s := s - 1 + end + if res_digit /= 0 then + target [target_offset + size] := res_digit + size := size + 1 + end + Result := size + else + if str_len < str_len.max_value then + from + i := chars_per_limb_l + until + i >= str_len + loop + res_digit := str [str_offset] + str_offset := str_offset + 1 + if base = 10 then + from + j := 9 - 1 + until + j = 0 + loop + res_digit := res_digit * 10 + str [str_offset].to_natural_32 + str_offset := str_offset + 1 + j := j - 1 + end + else + from + j := chars_per_limb_l - 1 + until + j = 0 + loop + res_digit := res_digit * base.to_natural_32 + str [str_offset].to_natural_32 + str_offset := str_offset + 1 + j := j - 1 + end + end + if size = 0 then + if res_digit /= 0 then + target [target_offset] := res_digit + size := 1 + end + else + mul_1 (target, target_offset, target, target_offset, size, big_base_l, carry) + cy_limb := carry.item + add_1 (target, target_offset, target, target_offset, size, res_digit, carry) + cy_limb := cy_limb + carry.item + if cy_limb /= 0 then + target [target_offset + size] := cy_limb + size := size + 1 + end + end + i := i + chars_per_limb_l + end + big_base_l := base.to_natural_32 + res_digit := str [str_offset] + str_offset := str_offset + 1 + if base = 10 then + from + j := str_len - (i - 9) - 1 + until + j <= 0 + loop + res_digit := res_digit * 10 + str [str_offset] + str_offset := str_offset + 1 + big_base_l := big_base_l * 10 + j := j - 1 + end + else + from + j := str_len - (i - chars_per_limb_l) - 1 + until + j <= 0 + loop + res_digit := res_digit * base.to_natural_32 + str [str_offset].to_natural_32 + str_offset := str_offset + 1 + big_base_l := big_base_l * base.to_natural_32 + j := j - 1 + end + end + if size = 0 then + if res_digit /= 0 then + target [target_offset] := res_digit + size := 1 + end + else + mul_1 (target, target_offset, target, target_offset, size, big_base_l, carry) + cy_limb := carry.item + add_1 (target, target_offset, target, target_offset, size, res_digit, carry) + cy_limb := cy_limb + carry.item + if cy_limb /= 0 then + target [target_offset + size] := cy_limb + size := size + 1 + end + end + Result := size + end + end + end +end diff --git a/library/crypto/eapml/facilities/special_comparison.e b/library/crypto/eapml/facilities/special_comparison.e new file mode 100644 index 00000000..07539e7f --- /dev/null +++ b/library/crypto/eapml/facilities/special_comparison.e @@ -0,0 +1,39 @@ +note + description: "Summary description for {NUMBER_COMPARISON}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "No nation was ever ruined by trade. - Benjamin Franklin" + +deferred class + SPECIAL_COMPARISON + +feature + + cmp (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER; size: INTEGER): INTEGER + local + i: INTEGER + x: NATURAL_32 + y: NATURAL_32 + do + Result := 0 + from + i := size - 1 + until + i < 0 or Result /= 0 + loop + x := op1 [op1_offset + i] + y := op2 [op2_offset + i] + if x /= y then + if x > y then + Result := 1 + else + Result := -1 + end + end + i := i - 1 + variant + i + 2 + end + end +end diff --git a/library/crypto/eapml/facilities/special_division.e b/library/crypto/eapml/facilities/special_division.e new file mode 100644 index 00000000..6aa5cf6b --- /dev/null +++ b/library/crypto/eapml/facilities/special_division.e @@ -0,0 +1,1102 @@ +note + description: "Summary description for {NUMBER_DIVISION}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Freedom is the emancipation from the arbitrary rule of other men. - Mortimer Adler (1902-2001)" + +deferred class + SPECIAL_DIVISION + +inherit + SPECIAL_ARITHMETIC + SPECIAL_COMPARISON + LIMB_MANIPULATION + SPECIAL_LOGIC + +feature + + bdivmod (qp: SPECIAL [NATURAL_32]; qp_offset_a: INTEGER; up: SPECIAL [NATURAL_32]; up_offset_a: INTEGER; usize_a: INTEGER; vp: SPECIAL [NATURAL_32]; vp_offset: INTEGER; vsize: INTEGER; d_a: INTEGER): NATURAL_32 + -- Computes (`up' / `vp') mod (2 ^ `d') + require + usize_a >= 1 + vsize >= 1 + usize_a * limb_bits >= d_a + vp.valid_index (vp_offset) + vp.valid_index (vp_offset + vsize - 1) + up.valid_index (up_offset_a) + up.valid_index (up_offset_a + usize_a - 1) + vp [vp_offset].bit_test (0) + local + v_inv: NATURAL_32 + hi: CELL [NATURAL_32] + lo: CELL [NATURAL_32] + q: NATURAL_32 + b: NATURAL_32 + junk: NATURAL_32 + d: INTEGER + up_offset: INTEGER + usize: INTEGER + qp_offset: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + qp_offset := qp_offset_a + up_offset := up_offset_a + usize := usize_a + d := d_a + create hi.put (0) + create lo.put (0) + v_inv := modlimb_invert (vp [vp_offset]) + if usize = 2 and vsize = 2 and (d = limb_bits or d = 2 * limb_bits) then + q := up [up_offset] * v_inv + umul_ppmm (hi, lo, q, vp [vp_offset]) + up [up_offset] := 0 + up [up_offset + 1] := up [up_offset + 1] - hi.item + q * vp [vp_offset + 1] + qp [qp_offset] := q + if d = 2 * limb_bits then + q := up [up_offset + 1] * v_inv + up [up_offset + 1] := 0 + qp [qp_offset + 1] := q + end + Result := 0 + else + from + until + d < limb_bits + loop + q := up [up_offset] * v_inv + submul_1 (up, up_offset, vp, vp_offset, usize.min (vsize), q, carry) + b := carry.item + if usize > vsize then + sub_1 (up, up_offset + vsize, up, up_offset + vsize, usize - vsize, b, carry) + junk := carry.item + end + d := d - limb_bits + up_offset := up_offset + 1 + usize := usize - 1 + qp [qp_offset] := q + qp_offset := qp_offset + 1 + end + if d /= 0 then + q := (up [up_offset] * v_inv).bit_and (((1).to_natural_32 |<< d) - 1) + if q <= 1 then + if q = 0 then + Result := 0 + else + sub_n (up, up_offset, up, up_offset, vp, vp_offset, usize.min (vsize), carry) + b := carry.item + if usize > vsize then + sub_1 (up, up_offset + vsize, up, up_offset + vsize, usize - vsize, b, carry) + junk := carry.item + end + Result := q + end + else + submul_1 (up, up_offset, vp, vp_offset, usize.min (vsize), q, carry) + b := carry.item + if usize > vsize then + sub_1 (up, up_offset + vsize, up, up_offset + vsize, usize - vsize, b, carry) + junk := carry.item + Result := q + end + end + else + Result := 0 + end + end + end + + dc_divrem_n (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; n: INTEGER_32): NATURAL_32 + local + scratch: SPECIAL [NATURAL_32] + do + create scratch.make_filled (0, n) + Result := dc_div_2_by_1 (target, target_offset, op1, op1_offset, op2, op2_offset, n, scratch, 0) + end + + dc_div_2_by_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; n: INTEGER_32; scratch: SPECIAL [NATURAL_32]; scratch_offset: INTEGER_32): NATURAL_32 + local + qhl: NATURAL_32 + cc: NATURAL_32 + n2: INTEGER_32 + target_cursor: INTEGER_32 + div_result: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + n2 := n // 2 + if n \\ 2 /= 0 then + target_cursor := target_offset + 1 + qhl := dc_div_3_by_2 (target, target_cursor + n2, op1, op1_offset + 2 + n2, op2, op2_offset + 1, n2, scratch, scratch_offset) + div_result := dc_div_3_by_2 (target, target_cursor, op1, op1_offset + 2, op2, op2_offset + 1, n2, scratch, scratch_offset) + add_1 (target, target_cursor + n2, target, target_cursor + n2, n2, div_result, carry) + qhl := qhl + carry.item + submul_1 (op1, op1_offset + 1, target, target_cursor, n - 1, op2 [op2_offset], carry) + cc := carry.item + sub_1 (op1, op1_offset + n, op1, op1_offset + n, 1, cc, carry) + cc := carry.item + if qhl /= 0 then + sub_1 (op1, op1_offset + n, op1, op1_offset + n, 1, op2 [op2_offset], carry) + cc := cc + carry.item + end + from + until + cc = 0 + loop + sub_1 (target, target_cursor, target, target_cursor, n - 1, 1, carry) + qhl := qhl - carry.item + add_n (op1, op1_offset + 1, op1, op1_offset + 1, op2, op2_offset, n, carry) + cc := cc - carry.item + end + div_result := sb_divrem_mn (target, target_offset, op1, op1_offset, n + 1, op2, op2_offset, n) + add_1 (target, target_cursor, target, target_cursor, n - 1, div_result, carry) + qhl := qhl + carry.item + else + qhl := dc_div_3_by_2 (target, target_offset + n2, op1, op1_offset + n2, op2, op2_offset, n2, scratch, scratch_offset) + div_result := dc_div_3_by_2 (target, target_offset, op1, op1_offset, op2, op2_offset, n2, scratch, scratch_offset) + add_1 (target, target_offset + n2, target, target_offset + n2, n2, div_result, carry) + qhl := qhl + carry.item + end + Result := qhl + end + + dc_div_3_by_2 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; n: INTEGER_32; scratch: SPECIAL [NATURAL_32]; scratch_offset: INTEGER_32): NATURAL_32 + local + twon: INTEGER_32 + qhl: NATURAL_32 + cc: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + twon := n + n + if n < 3 * 32 then + qhl := sb_divrem_mn (target, target_offset, op1, op1_offset + n, twon, op2, op2_offset + n, n) + else + qhl := dc_div_2_by_1 (target, target_offset, op1, op1_offset + n, op2, op2_offset + n, n, scratch, scratch_offset) + end + mul_n (scratch, scratch_offset, target, target_offset, op2, op2_offset, n) + sub_n (op1, op1_offset, op1, op1_offset, scratch, scratch_offset, twon, carry) + cc := carry.item + if qhl /= 0 then + sub_n (op1, op1_offset + n, op1, op1_offset + n, op2, op2_offset, n, carry) + cc := cc + carry.item + end + from + until + cc = 0 + loop + sub_1 (target, target_offset, target, target_offset, n, 1, carry) + qhl := qhl - carry.item + add_n (op1, op1_offset, op1, op1_offset, op2, op2_offset, twon, carry) + cc := cc - carry.item + end + Result := qhl + end + + divexact_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; src: SPECIAL [NATURAL_32]; src_offset: INTEGER; size_a: INTEGER; divisor_a: NATURAL_32) + local + i: INTEGER + c: NATURAL_32 + h: CELL [NATURAL_32] + l: NATURAL_32 + ls: NATURAL_32 + s: NATURAL_32 + s_next: NATURAL_32 + inverse: NATURAL_32 + dummy: CELL [NATURAL_32] + shift: INTEGER + divisor: NATURAL_32 + size: INTEGER + do + size := size_a + divisor := divisor_a + create h.put (0) + create dummy.put (0) + s := src [src_offset] + if size = 1 then + target [target_offset] := s // divisor + elseif not divisor.bit_test (0) then + shift := trailing_zeros (divisor) + divisor := divisor |>> shift + else + shift := 0 + end + inverse := limb_inverse (divisor) + if shift /= 0 then + c := 0 + i := 0 + size := size - 1 + from + until + i >= size + loop + s_next := src [src_offset + i + 1] + ls := (s |>> shift).bit_or (s_next |<< (limb_bits - shift)) + s := s_next + l := ls - c + c := (l > ls).to_integer.to_natural_32 + l := l * inverse + target [target_offset + i] := l + umul_ppmm (h, dummy, l, divisor) + c := c + h.item + i := i + 1 + end + ls := s |>> shift + l := ls - c + l := (l * inverse) + target [target_offset + i] := l + else + l := s * inverse + target [target_offset] := l + i := 1 + c := 0 + from + until + i >= size + loop + umul_ppmm (h, dummy, l, divisor) + c := c + h.item + s := src [src_offset + i] + l := s - c + c := (l > s).to_integer.to_natural_32 + l := l * inverse + target [target_offset + i] := l + i := i + 1 + end + end + end + + divrem_2 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32): NATURAL_32 + require + op2.valid_index (op2_offset) + op2.valid_index (op2_offset + 1) + op1_count >= 2 + op2 [op2_offset + 1].bit_and (0x80000000) /= 0 + local + most_significant_q_limb: NATURAL_32 + i: INTEGER_32 + n1: CELL [NATURAL_32] + n0: CELL [NATURAL_32] + n2: NATURAL_32 + d1: NATURAL_32 + d0: NATURAL_32 + d1inv: NATURAL_32 + op1_cursor: INTEGER_32 + q: CELL [NATURAL_32] + r: CELL [NATURAL_32] + continue: BOOLEAN + do + create n1.put (0) + create n0.put (0) + create q.put (0) + create r.put (0) + op1_cursor := op1_offset + op1_count - 2 + d1 := op2 [op2_offset + 1] + d0 := op2 [op2_offset] + n1.put (op1 [op1_cursor + 1]) + n0.put (op1 [op1_cursor]) + if n1.item >= d1 and (n1.item > d1 or n0.item >= d0) then + sub_ddmmss (n1, n0, n1.item, n0.item, d1, d0) + most_significant_q_limb := 1 + end + d1inv := limb_inverse (d1) + from + i := op1_count - 2 - 1 + until + i < 0 + loop + continue := False + op1_cursor := op1_cursor - 1 + if n1.item = d1 then + q.put (0xffffffff) + r.put (n0.item + d1) + if r.item < d1 then + add_ssaaaa (n1, n0, r.item - d0, op1 [op1_cursor], 0, d0) + target [target_offset + i] := q.item + continue := True + else + n1.put (d0 - (d0 /= 0).to_integer.to_natural_32) + n0.put (0 - d0) + end + else + udiv_qrnnd_preinv (q, r, n1.item, n0.item, d1, d1inv) + umul_ppmm (n1, n0, d0, q.item) + end + if not continue then + n2 := op1 [op1_cursor] + from + continue := True + until + not continue + loop + if n1.item > r.item or (n1.item = r.item and n0.item > n2) then + q.put (q.item - 1) + sub_ddmmss (n1, n0, n1.item, n0.item, 0, d0) + r.put (r.item + d1) + if r.item >= d1 then + else + continue := False + end + else + continue := False + end + end + target [target_offset + i] := q.item + sub_ddmmss (n1, n0, r.item, n2, n1.item, n0.item) + end + i := i - 1 + end + op1 [op1_cursor + 1] := n1.item + op1 [op1_cursor] := n0.item + Result := most_significant_q_limb + end + + sub_ddmmss (sh: CELL [NATURAL_32]; sl: CELL [NATURAL_32]; ah: NATURAL_32; al: NATURAL_32; bh: NATURAL_32; bl: NATURAL_32) + local + x: NATURAL_32 + do + x := al - bl + sh.put (ah - bh - (al < bl).to_integer.to_natural_32) + sl.put (x) + end + + divrem_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; d: NATURAL_32): NATURAL_32 + require + d /= 0 + op1_count >= 0 + local + n: INTEGER_32 + i: INTEGER_32 + n1: NATURAL_32 + n0: NATURAL_32 + r: NATURAL_32 + target_cursor: INTEGER_32 + q: NATURAL_32 + norm: INTEGER_32 + un: INTEGER_32 + dinv: NATURAL_32 + d_cursor: NATURAL_32 + q_res: CELL [NATURAL_32] + r_res: CELL [NATURAL_32] + do + create q_res.put (0) + create r_res.put (0) + un := op1_count + n := op1_count + if n = 0 then + Result := 0 + else + target_cursor := target_offset + n - 1 + if d.bit_test (limb_high_bit) then + r := op1 [op1_count - 1] + q := (r >= d).to_integer.to_natural_32 + target [target_cursor] := q + target_cursor := target_cursor - 1 + r := r - d.bit_and (0 - q) + n := n - 1 + un := un - 1 + dinv := limb_inverse (d) + from + i := un - 1 + until + i < 0 + loop + n0 := op1 [i] + udiv_qrnnd_preinv (q_res, r_res, r, n0, d, dinv) + target [target_cursor] := q_res.item + r := r_res.item + target_cursor := target_cursor - 1 + i := i - 1 + end + Result := r + else + n1 := op1 [op1_count - 1] + Result := r - 1 + if n1 < d then + r := n1 + target [target_cursor] := 0 + target_cursor := target_cursor - 1 + n := n - 1 + if n = 0 then + Result := r + else + un := un - 1 + end + end + if Result /= r then + norm := leading_zeros (d) + d_cursor := d |<< norm + r := r |<< norm + dinv := limb_inverse (d_cursor) + if un /= 0 then + n1 := op1 [un - 1] + r := r.bit_or (n1.bit_shift_right (-norm)) + from + i := un - 2 + until + i < 0 + loop + n0 := op1 [i] + udiv_qrnnd_preinv (q_res, r_res, r, n1.bit_shift_left (norm).bit_or (n0.bit_shift_right (0 - norm)), d_cursor, dinv) + r := r_res.item + target [target_cursor] := q_res.item + target_cursor := target_cursor - 1 + n1 := n0 + i := i - 1 + end + udiv_qrnnd_preinv (q_res, r_res, r, n1.bit_shift_left (norm), d_cursor, dinv) + r := r_res.item + target [target_cursor] := q_res.item + target_cursor := target_cursor - 1 + end + Result := r.bit_shift_right (norm) + end + end + end + end + + udiv_qrnnd_preinv (q: CELL [NATURAL_32]; r: CELL [NATURAL_32]; nh: NATURAL_32; nl: NATURAL_32; d: NATURAL_32; di: NATURAL_32) + local + n2: NATURAL_32 + n10: NATURAL_32 + nmask: NATURAL_32 + nadj: NATURAL_32 + q1: NATURAL_32 + xh: CELL [NATURAL_32] + xl: CELL [NATURAL_32] + do + create xh.put (0) + create xl.put (0) + n2 := nh + n10 := nl + nmask := limb_highbit_to_mask (n10) + nadj := n10 + (nmask.bit_and (d)) + umul_ppmm (xh, xl, di, n2 - nmask) + add_ssaaaa (xh, xl, xh.item, xl.item, n2, nadj) + q1 := xh.item.bit_not + umul_ppmm (xh, xl, q1, d) + add_ssaaaa (xh, xl, xh.item, xl.item, nh, nl) + xh.put (xh.item - d) + r.put (xl.item + d.bit_and (xh.item)) + q.put (xh.item - q1) + end + + udiv_qrnd_unnorm (q: CELL [NATURAL_32]; r: CELL [NATURAL_32]; n: NATURAL_32; d: NATURAL_32) + do + q.put (n // d) + r.put (n \\ d) + end + + add_ssaaaa (sh: CELL [NATURAL_32]; sl: CELL [NATURAL_32]; ah: NATURAL_32; al: NATURAL_32; bh: NATURAL_32; bl: NATURAL_32) + local + x: NATURAL_32 + do + x := al + bl + sh.put (ah + bh + (x < al).to_integer.to_natural_32) + sl.put (x) + end + + limb_highbit_to_mask (limb: NATURAL_32): NATURAL_32 + do + if limb.bit_test (31) then + Result := Result.bit_not + end + end + + mod_1 (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count_a: INTEGER; d_a: NATURAL_32; remainder: CELL [NATURAL_32]) + -- Divides `op1' by `d_a' and places remainder in `remainder' + require + op1_count_a >= 0 + d_a /= 0 + local + i: INTEGER + n1: NATURAL_32 + n0: NATURAL_32 + r: CELL [NATURAL_32] + dummy: CELL [NATURAL_32] + op1_count: INTEGER + inv: NATURAL_32 + norm: INTEGER + d: NATURAL_32 + do + create r.put (0) + create dummy.put (0) + d := d_a + op1_count := op1_count_a + if op1_count = 0 then + remainder.put (0) + else + if d.bit_test (limb_high_bit) then + r.put (op1 [op1_offset - 1]) + if r.item >= d then + r.put (r.item - d) + end + op1_count := op1_count - 1 + if op1_count = 0 then + remainder.put (r.item) + else + inv := limb_inverse (d) + from + i := op1_count - 1 + until + i < 0 + loop + n0 := op1 [op1_offset + i] + udiv_qrnnd_preinv (dummy, r, r.item, n0, d, inv) + i := i - 1 + end + remainder.put (r.item) + end + else + r.put (op1 [op1_offset + op1_count - 1]) + if r.item < d and op1_count - 1 = 0 then + remainder.put (r.item) + else + if r.item < d then + op1_count := op1_count - 1 + else + r.put (0) + end + norm := leading_zeros (d) + d := d |<< norm + n1 := op1 [op1_offset + op1_count - 1] + r.put ((r.item |<< norm).bit_or (n1 |>> (limb_bits - norm))) + inv := limb_inverse (d) + from + i := op1_count - 2 + until + i < 0 + loop + n0 := op1 [op1_offset + i] + udiv_qrnnd_preinv (dummy, r, r.item, (n1 |<< norm).bit_or (n0 |>> (limb_bits - norm)), d, inv) + n1 := n0 + i := i - 1 + end + udiv_qrnnd_preinv (dummy, r, r.item, n1 |<< norm, d, inv) + remainder.put (r.item |>> norm) + end + end + end + end + + preinv_divrem_1 (qp: SPECIAL [NATURAL_32]; qp_offset_a: INTEGER; xsize: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; size_a: INTEGER; d_unnorm: NATURAL_32; dinv: NATURAL_32; shift: INTEGER): NATURAL_32 + require + xsize >= 0 + size_a >= 1 + d_unnorm /= 0 + local + ahigh: NATURAL_32 + qhigh: NATURAL_32 + r: CELL [NATURAL_32] + q: CELL [NATURAL_32] + i: INTEGER + n1: NATURAL_32 + n0: NATURAL_32 + d: NATURAL_32 + qp_offset: INTEGER + size: INTEGER + done_integer: BOOLEAN + do + create r.put (0) + create q.put (0) + qp_offset := qp_offset_a + size := size_a + ahigh := ap [ap_offset + size - 1] + d := d_unnorm |<< shift + qp_offset := qp_offset + (size + xsize - 1) + if shift = 0 then + r.put (ahigh) + qhigh := (r.item >= d).to_integer.to_natural_32 + if qhigh /= 0 then + r.put (r.item - d) + end + qp [qp_offset] := qhigh + qp_offset := qp_offset - 1 + size := size - 1 + from + i := size - 1 + until + i < 0 + loop + n0 := ap [ap_offset + i] + udiv_qrnnd_preinv (q, r, r.item, n0, d, dinv) + qp [qp_offset] := q.item + qp_offset := qp_offset - 1 + i := i - 1 + end + done_integer := True + else + r.put (0) + if ahigh < d_unnorm then + r.put (ahigh |<< shift) + qp [qp_offset] := 0 + qp_offset := qp_offset - 1 + size := size - 1 + if size = 0 then + done_integer := True + end + end + if not done_integer then + n1 := ap [ap_offset + size - 1] + r.put (r.item.bit_or (n1 |>> (limb_bits - shift))) + from + i := size - 2 + until + i < 0 + loop + n0 := ap [ap_offset + i] + udiv_qrnnd_preinv (q, r, r.item, (n1 |<< shift).bit_or (n0 |>> (limb_bits - shift)), d, dinv) + qp [qp_offset] := q.item + qp_offset := qp_offset - 1 + n1 := n0 + i := i - 1 + end + udiv_qrnnd_preinv (q, r, r.item, n1 |<< shift, d, dinv) + qp [qp_offset] := q.item + qp_offset := qp_offset - 1 + end + end + from + i := 0 + until + i >= xsize + loop + udiv_qrnnd_preinv (q, r, r.item, 0, d, dinv) + qp [qp_offset] := q.item + qp_offset := qp_offset - 1 + i := i + 1 + end + Result := r.item |>> shift + end + + sb_divrem_mn (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; op2_count: INTEGER_32): NATURAL_32 + -- Base case division + require + op2_count > 2 + op1_count >= op2_count + op2 [op2_offset + op2_count - 1].bit_test (limb_high_bit) + local + most_significant_q_limb: NATURAL_32 + qn: INTEGER_32 + i: INTEGER_32 + dx: NATURAL_32 + d1: NATURAL_32 + n0: NATURAL_32 + dxinv: NATURAL_32 + junk: NATURAL_32 + q: CELL [NATURAL_32] + nx: NATURAL_32 + cy_limb: NATURAL_32 + rx: NATURAL_32 + r1: CELL [NATURAL_32] + r0: NATURAL_32 + p1: CELL [NATURAL_32] + p0: CELL [NATURAL_32] + cy1: NATURAL_32 + cy2: NATURAL_32 + op1_offset: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + create q.put (0) + create r1.put (0) + create p1.put (0) + create p0.put (0) + op1_offset := op1_offset_a + qn := op1_count - op2_count + op1_offset := op1_offset + qn + dx := op2 [op2_offset + op2_count - 1] + d1 := op2 [op2_offset + op2_count - 2] + n0 := op1 [op1_offset + op2_count - 1] + if n0 >= dx then + if n0 > dx or cmp (op1, op1_offset, op2, op2_offset, op2_count - 1) >= 0 then + sub_n (op1, op1_offset, op1, op1_offset, op2, op2_offset, op2_count, carry) + junk := carry.item + most_significant_q_limb := 1 + end + end + dxinv := limb_inverse (dx) + from + i := qn - 1 + until + i < 0 + loop + nx := op1 [op1_offset + op2_count - 1] + op1_offset := op1_offset - 1 + if nx = dx then + q.put (0xffffffff) + submul_1 (op1, op1_offset, op2, op2_offset, op2_count, q.item, carry) + cy_limb := carry.item + if nx /= cy_limb then + add_n (op1, op1_offset, op1, op1_offset, op2, op2_offset, op2_count, carry) + junk := carry.item + q.put (q.item - 1) + end + target [target_offset + i] := q.item + else + udiv_qrnnd_preinv (q, r1, nx, op1 [op1_offset + op2_count - 1], dx, dxinv) + umul_ppmm (p1, p0, d1, q.item) + r0 := op1 [op1_offset + op2_count - 2] + rx := 0 + if r1.item < p1.item or (r1.item = p1.item and r0 < p0.item) then + p1.put (p1.item - (p0.item < d1).to_integer.to_natural_32) + p0.put (p0.item - d1) + q.put (q.item - 1) + r1.put (r1.item + dx) + rx := (r1.item < dx).to_integer.to_natural_32 + end + p1.put (p1.item + (r0 < p0.item).to_integer.to_natural_32) + rx := rx - (r1.item < p1.item).to_integer.to_natural_32 + r1.put (r1.item - p1.item) + r0 := r0 - p0.item + submul_1 (op1, op1_offset, op2, op2_offset, op2_count - 2, q.item, carry) + cy_limb := carry.item + cy1 := (r0 < cy_limb).to_integer.to_natural_32 + r0 := r0 - cy_limb + cy2 := (r1.item < cy1).to_integer.to_natural_32 + r1.put (r1.item - cy1) + op1 [op1_offset + op2_count - 1] := r1.item + op1 [op1_offset + op2_count - 2] := r0 + if cy2 /= rx then + add_n (op1, op1_offset, op1, op1_offset, op2, op2_offset, op2_count, carry) + junk := carry.item + q.put (q.item - 1) + end + target [target_offset + i] := q.item + end + i := i - 1 + end + Result := most_significant_q_limb + end + + tdiv_qr (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32) + require + denominator_count >= 0 + numerator_count >= 0 + denominator_count = 0 or denominator [denominator_offset + denominator_count - 1] /= 0 + do + inspect denominator_count + when 0 then + (create {DIVIDE_BY_ZERO}).raise + when 1 then + remainder [remainder_offset] := divrem_1 (target, target_offset, numerator, numerator_offset, numerator_count, denominator [denominator_offset]) + when 2 then + tdiv_qr_two_case (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count) + else + tdiv_qr_large_case (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count) + end + end + + tdiv_qr_large_numerator (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count_a: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32; adjust: INTEGER_32) + local + d2p: SPECIAL [NATURAL_32] + d2p_offset: INTEGER_32 + cy: NATURAL_32 + cnt: INTEGER_32 + n2p: SPECIAL [NATURAL_32] + n2p_offset: INTEGER_32 + numerator_count: INTEGER_32 + junk: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + numerator_count := numerator_count_a + target [target_offset + numerator_count - denominator_count] := 0 + if not denominator [denominator_offset + denominator_count - 1].bit_test (31) then + cnt := leading_zeros (denominator [denominator_offset + denominator_count - 1]) + create d2p.make_filled (0, denominator_count) + d2p_offset := 0 + lshift (d2p, d2p_offset, denominator, denominator_offset, denominator_count, cnt, carry) + junk := carry.item + create n2p.make_filled (0, numerator_count + 1) + n2p_offset := 0 + lshift (n2p, n2p_offset, numerator, numerator_offset, numerator_count, cnt, carry) + cy := carry.item + n2p [n2p_offset + numerator_count] := cy + numerator_count := numerator_count + adjust + else + cnt := 0 + d2p := denominator + d2p_offset := denominator_offset + create n2p.make_filled (0, numerator_count + 1) + n2p_offset := 0 + n2p.copy_data (numerator, numerator_offset, n2p_offset, numerator_count) + n2p [n2p_offset + numerator_count] := 0 + numerator_count := numerator_count + adjust + end + if denominator_count < 3 * 32 then + junk := sb_divrem_mn (target, target_offset, n2p, n2p_offset, numerator_count, d2p, d2p_offset, denominator_count) + else + tdiv_qr_large_denominator (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count, n2p, n2p_offset, d2p, d2p_offset, numerator_count) + end + if cnt /= 0 then + rshift (remainder, remainder_offset, n2p, n2p_offset, denominator_count, cnt, carry) + junk := carry.item + else + remainder.copy_data (n2p, n2p_offset, remainder_offset, denominator_count) + end + end + + tdiv_qr_large_denominator (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32; n2p: SPECIAL [NATURAL_32]; n2p_offset_a: INTEGER_32; d2p: SPECIAL [NATURAL_32]; d2p_offset_a: INTEGER_32; nn_a: INTEGER_32) + local + q2p: SPECIAL [NATURAL_32] + q2p_offset: INTEGER_32 + q1: NATURAL_32 + junk: NATURAL_32 + n2p_offset: INTEGER_32 + d2p_offset: INTEGER_32 + nn: INTEGER_32 + do + nn := nn_a + n2p_offset := n2p_offset_a + d2p_offset := d2p_offset_a + q2p := target + q2p_offset := target_offset + nn - denominator_count + n2p_offset := n2p_offset + nn - denominator_count + from + until + nn < 2 * denominator_count + loop + q2p_offset := q2p_offset - denominator_count + n2p_offset := n2p_offset - denominator_count + junk := dc_divrem_n (q2p, q2p_offset, n2p, n2p_offset, d2p, d2p_offset, denominator_count) + nn := nn - denominator_count + end + if nn /= denominator_count then + n2p_offset := n2p_offset - nn - denominator_count + q1 := target [target_offset + nn - denominator_count] + tdiv_qr (target, target_offset, n2p, n2p_offset, n2p, n2p_offset, nn, d2p, d2p_offset, denominator_count) + target [target_offset + nn - denominator_count] := q1 + end + end + + tdiv_qr_large_case (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32) + local + adjust: INTEGER_32 + do + adjust := (numerator [numerator_offset + numerator_count - 1] >= denominator [denominator_offset + denominator_count - 1]).to_integer + if numerator_count + adjust >= 2 * denominator_count then + tdiv_qr_large_numerator (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count, adjust) + else + tdiv_qr_small_numerator (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count, adjust) + end + end + + tdiv_qr_small_numerator (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32; adjust: INTEGER_32) + local + qn: INTEGER_32 + do + qn := numerator_count - denominator_count + target [target_offset + qn] := 0 + qn := qn + adjust + if qn = 0 then + remainder.copy_data (numerator, numerator_offset, remainder_offset, denominator_count) + else + tdiv_qr_non_zero_quotient (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count, adjust, qn) + end + end + + tdiv_qr_non_zero_quotient (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32; adjust: INTEGER_32; qn: INTEGER_32) + local + d2p: SPECIAL [NATURAL_32] + d2p_offset: INTEGER_32 + cy: NATURAL_32 + cnt: INTEGER_32 + n2p: SPECIAL [NATURAL_32] + n2p_offset: INTEGER_32 + in: INTEGER_32 + rn: INTEGER_32 + junk: NATURAL_32 + dl: NATURAL_32 + x: NATURAL_32 + h: CELL [NATURAL_32] + dummy: CELL [NATURAL_32] + cy1: NATURAL_32 + cy2: NATURAL_32 + quotient_too_large: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + in := denominator_count - qn + if not denominator [denominator_offset + denominator_count - 1].bit_test (limb_high_bit) then + cnt := leading_zeros (denominator [denominator_offset + denominator_count - 1]) + create d2p.make_filled (0, qn) + d2p_offset := 0 + lshift (d2p, d2p_offset, denominator, denominator_offset + in, qn, cnt, carry) + junk := carry.item + d2p [d2p_offset] := d2p [d2p_offset].bit_or ((denominator [denominator_offset + in - 1]) |>> (limb_bits - cnt)) + create n2p.make_filled (0, 2 * qn + 1) + n2p_offset := 0 + lshift (n2p, n2p_offset, numerator, numerator_offset + numerator_count - 2 * qn, 2 * qn, cnt, carry) + cy := carry.item + if adjust /= 0 then + n2p [n2p_offset + 2 * qn] := cy + n2p_offset := n2p_offset + 1 + else + n2p [n2p_offset] := n2p [n2p_offset].bit_or ((numerator [numerator_offset + numerator_count - 2 * qn - 1]) |>> (limb_bits - cnt)) + end + else + cnt := 0 + d2p := denominator + d2p_offset := denominator_offset + in + create n2p.make_filled (0, 2 * qn + 1) + n2p_offset := 0 + n2p.copy_data (numerator, numerator_offset + numerator_count - 2 * qn, n2p_offset, 2 * qn) + if adjust /= 0 then + n2p [n2p_offset + 2 * qn] := 0 + n2p_offset := n2p_offset + 1 + end + end + tdiv_qr_internal_divide (target, target_offset, n2p, n2p_offset, d2p, d2p_offset, qn) + rn := qn + create h.put (0) + create dummy.put (0) + if in - 2 < 0 then + dl := 0 + else + dl := denominator [denominator_offset + in - 2] + end + x := (denominator [denominator_offset + in - 1] |<< cnt).bit_or ((dl |>> 1) |>> (cnt.bit_not \\ limb_bits)) + umul_ppmm (h, dummy, x, target [target_offset + qn - 1]) + if n2p [n2p_offset + qn - 1] < h.item then + decr_u (target, target_offset, 1) + add_n (n2p, n2p_offset, n2p, n2p_offset, d2p, d2p_offset, qn, carry) + cy := carry.item + if cy /= 0 then + n2p [n2p_offset + qn] := cy + rn := rn + 1 + end + end + if cnt /= 0 then + lshift (n2p, n2p_offset, n2p, n2p_offset, rn, limb_bits - cnt, carry) + cy1 := carry.item + n2p [n2p_offset] := n2p [n2p_offset].bit_or (numerator [numerator_offset + in - 1].bit_and ((0xffffffff).to_natural_32 |>> cnt)) + submul_1 (n2p, n2p_offset, target, target_offset, qn, denominator [denominator_offset + in - 1].bit_and ((0xffffffff).to_natural_32 |>> cnt), carry) + cy2 := carry.item + if qn /= rn then + n2p [n2p_offset + qn] := n2p [n2p_offset + qn] - cy2 + else + n2p [n2p_offset + qn] := cy1 - cy2 + quotient_too_large := (cy1 < cy2).to_integer.to_natural_32 + rn := rn + 1 + end + in := in - 1 + end + tdiv_qr_shift_result (target, target_offset, remainder, remainder_offset, numerator, numerator_offset, numerator_count, denominator, denominator_offset, denominator_count, adjust, qn, n2p, n2p_offset, d2p, d2p_offset, rn, in, cnt, quotient_too_large) + end + + tdiv_qr_internal_divide (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; qn: INTEGER_32) + local + junk: NATURAL_32 + do + if qn = 1 then + tdiv_qr_internal_divide_1 (target, target_offset, numerator, numerator_offset, denominator, denominator_offset) + elseif qn = 2 then + junk := divrem_2 (target, target_offset, numerator, numerator_offset, 4, denominator, denominator_offset) + elseif qn < 3 * 32 then + junk := sb_divrem_mn (target, target_offset, numerator, numerator_offset, 2 * qn, denominator, denominator_offset, qn) + else + junk := dc_divrem_n (target, target_offset, numerator, numerator_offset, denominator, denominator_offset, qn) + end + end + + tdiv_qr_internal_divide_1 (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER) + local + q0: TUPLE [q0: NATURAL_32] + r0: TUPLE [r0: NATURAL_32] + do + create q0 + create r0 + udiv_qrnnd (q0, r0, numerator [numerator_offset + 1], numerator [numerator_offset], denominator [denominator_offset]) + numerator [numerator_offset] := r0.r0 + target [target_offset] := q0.q0 + end + + tdiv_qr_shift_result (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32; adjust: INTEGER_32; qn: INTEGER_32; n2p: SPECIAL [NATURAL_32]; n2p_offset: INTEGER_32; d2p: SPECIAL [NATURAL_32]; d2p_offset: INTEGER_32; rn_a: INTEGER_32; in: INTEGER_32; cnt: INTEGER_32; quotient_too_large_a: NATURAL_32) + local + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER_32 + junk: NATURAL_32 + goto: BOOLEAN + cy: NATURAL_32 + rn: INTEGER_32 + quotient_too_large: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + quotient_too_large := quotient_too_large_a + rn := rn_a + create tp.make_filled (0, denominator_count) + tp_offset := 0 + if in < qn and in = 0 then + if in = 0 then + remainder.copy_data (n2p, n2p_offset, remainder_offset, rn) + goto := True + else + mul (tp, tp_offset, target, target_offset, qn, denominator, denominator_offset, in, carry) + junk := carry.item + end + else + mul (tp, tp_offset, denominator, denominator_offset, in, target, target_offset, qn, carry) + junk := carry.item + end + if not goto then + sub (n2p, n2p_offset, n2p, n2p_offset, rn, tp, tp_offset + in, qn, carry) + cy := carry.item + remainder.copy_data (n2p, n2p_offset, remainder_offset + in, denominator_count - in) + quotient_too_large := quotient_too_large.bit_or (cy) + sub_n (remainder, remainder_offset, numerator, numerator_offset, tp, tp_offset, in, carry) + cy := carry.item + sub_1 (remainder, remainder_offset + in, remainder, remainder_offset + in, rn, cy, carry) + cy := carry.item + quotient_too_large := quotient_too_large.bit_or (cy) + end + if quotient_too_large /= 0 then + decr_u (target, target_offset, 1) + add_n (remainder, remainder_offset, remainder, remainder_offset, denominator, denominator_offset, denominator_count, carry) + junk := carry.item + end + end + + tdiv_qr_two_case (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; remainder: SPECIAL [NATURAL_32]; remainder_offset: INTEGER_32; numerator: SPECIAL [NATURAL_32]; numerator_offset: INTEGER_32; numerator_count: INTEGER_32; denominator: SPECIAL [NATURAL_32]; denominator_offset: INTEGER_32; denominator_count: INTEGER_32) + local + d2p: SPECIAL [NATURAL_32] + d2p_offset: INTEGER_32 + qhl: NATURAL_32 + cy: NATURAL_32 + cnt: INTEGER_32 + dtmp: SPECIAL [NATURAL_32] + n2p: SPECIAL [NATURAL_32] + n2p_offset: INTEGER_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + create dtmp.make_filled (0, 2) + if not denominator [denominator_offset + 1].bit_test (31) then + cnt := leading_zeros (denominator [denominator_offset + 1]) + d2p := dtmp + d2p [d2p_offset + 1] := (denominator [denominator_offset + 1] |<< cnt).bit_or (denominator [denominator_offset] |>> (limb_bits - cnt)) + d2p [d2p_offset] := denominator [denominator_offset] |<< cnt + create n2p.make_filled (0, numerator_count + 1) + lshift (n2p, 0, numerator, numerator_offset, numerator_count, cnt, carry) + cy := carry.item + n2p [numerator_count] := cy + qhl := divrem_2 (target, target_offset, n2p, n2p_offset, numerator_count + (cy /= 0).to_integer, d2p, d2p_offset) + if cy = 0 then + target [target_offset + numerator_count - 2] := qhl + end + remainder [remainder_offset] := (n2p [0] |>> cnt).bit_or (n2p [1] |<< (limb_bits - cnt)) + remainder [remainder_offset + 1] := n2p [1] |>> cnt + else + d2p := denominator + d2p_offset := denominator_offset + create n2p.make_filled (0, numerator_count) + n2p.copy_data (numerator, numerator_offset, 0, numerator_count) + qhl := divrem_2 (target, target_offset, n2p, 0, numerator_count, d2p, d2p_offset) + target [target_offset + numerator_count - 2] := qhl + remainder [remainder_offset] := n2p [0] + remainder [remainder_offset + 1] := n2p [1] + end + end +end diff --git a/library/crypto/eapml/facilities/special_gcd.e b/library/crypto/eapml/facilities/special_gcd.e new file mode 100644 index 00000000..484846dc --- /dev/null +++ b/library/crypto/eapml/facilities/special_gcd.e @@ -0,0 +1,1103 @@ +note + description: "Summary description for {NUMBER_GCD}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "My reading of history convinces me that most bad government results from too much government. - Thomas Jefferson." + +deferred class + SPECIAL_GCD + +inherit + SPECIAL_LOGIC + LIMB_MANIPULATION + SPECIAL_ARITHMETIC + SPECIAL_DIVISION + SPECIAL_UTILITY + +feature + + find_a (cp0: NATURAL_32; cp1: NATURAL_32): NATURAL_32 + local + leading_zero_bits: INTEGER + n1_l: NATURAL_32 + n1_h: NATURAL_32 + n2_l: NATURAL_32 + n2_h: NATURAL_32 + i: INTEGER + tmp: NATURAL_32 + do + n1_l := cp0 + n1_h := cp1 + n2_l := 0 - n1_l + n2_h := n1_h.bit_not + from + until + n2_h = 0 + loop + if not n2_h.bit_test (limb_high_bit - leading_zero_bits) then + i := leading_zeros (n2_h) + i := i - leading_zero_bits + leading_zero_bits := leading_zero_bits + i + n2_h := (n2_h |<< i).bit_or (n2_l |>> (limb_bits - i)) + n2_l := n2_l |<< i + from + until + i = 0 + loop + if n1_h > n2_h or (n1_h = n2_h and n1_l >= n2_l) then + n1_h := n1_h - (n2_h + (n1_l < n2_l).to_integer.to_natural_32) + n1_l := (n1_l - n2_l) + end + n2_l := (n2_l |>> 1).bit_or (n2_h |<< (limb_bits - 1)) + n2_h := n2_h |>> 1 + i := i - 1 + end + end + if n1_h > n2_h or (n1_h = n2_h and n1_l >= n2_l) then + n1_h := n1_h - (n2_h + (n1_l < n2_l).to_integer.to_natural_32) + n1_l := n1_l - n2_l + end + tmp := n1_h + n1_h := n2_h + n2_h := tmp + tmp := n1_l + n1_l := n2_l + n2_l := tmp + end + Result := n2_l + end + + gcd_2 (vp: SPECIAL [NATURAL_32]; vp_offset: INTEGER; up: SPECIAL [NATURAL_32]; up_offset: INTEGER): INTEGER + local + u0: NATURAL_32 + u1: NATURAL_32 + v0: NATURAL_32 + v1: NATURAL_32 + vsize: INTEGER + r: INTEGER + do + u0 := up [0] + u1 := up [1] + v0 := vp [0] + v1 := vp [1] + from + until + u1 = v1 or u0 = v0 + loop + if u1 > v1 then + u1 := u1 - (v1 + (u0 < v0).to_integer.to_natural_32) + u0 := u0 - v0 + r := trailing_zeros (u0) + u0 := (u1 |<< (limb_bits - r)).bit_or (u0 |>> r) + u1 := u1 |>> r + else + v1 := v1 - (u1 + (v0 < u0).to_integer.to_natural_32) + v0 := v0 - u0 + r := trailing_zeros (v0) + v0 := (v1 |<< (limb_bits - r)).bit_or (v0 |>> r) + v1 := v1 |>> r + end + end + vp [vp_offset] := v0 + vp [vp_offset + 1] := v1 + vsize := 1 + (v1 /= 0).to_integer + if u1 = v1 and u0 = v0 then + Result := vsize + else + if u0 = v0 then + if v1 > v1 then + v0 := u1 - v1 + else + v0 := v1 - u1 + end + else + if u0 > v0 then + v0 := u0 - v0 + else + v0 := v0 - u0 + end + end + vp [vp_offset] := gcd_1 (vp, vp_offset, vsize, v0) + Result := 1 + end + end + + gcd (gp: SPECIAL [NATURAL_32]; gp_offset: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; ap_count: INTEGER; bp: SPECIAL [NATURAL_32]; bp_offset: INTEGER; n: INTEGER): INTEGER + do + Result := basic_gcd (gp, gp_offset, ap, ap_offset, ap_count, bp, bp_offset, n) + ensure + Result > 0 + Result <= ap_count + Result <= n + end + + gcd_1 (up: SPECIAL [NATURAL_32]; up_offset: INTEGER; size: INTEGER; vlimb_a: NATURAL_32): NATURAL_32 + require + size >= 1 + vlimb_a /= 0 + local + remainder: CELL [NATURAL_32] + ulimb: NATURAL_32 + zero_bits: INTEGER + u_low_zero_bits: INTEGER + tmp: NATURAL_32 + vlimb: NATURAL_32 + maybe: BOOLEAN + done: BOOLEAN + do + create remainder.put (0) + vlimb := vlimb_a + ulimb := up [up_offset] + zero_bits := trailing_zeros (vlimb) + vlimb := vlimb |>> zero_bits + if size > 1 then + if ulimb /= 0 then + u_low_zero_bits := trailing_zeros (ulimb) + zero_bits := zero_bits.min (u_low_zero_bits) + end + mod_1 (up, up_offset, size, vlimb, remainder) + ulimb := remainder.item + if ulimb = 0 then + done := True + else + maybe := True + end + else + u_low_zero_bits := trailing_zeros (ulimb) + ulimb := ulimb |>> u_low_zero_bits + zero_bits := zero_bits.min (u_low_zero_bits) + if vlimb > ulimb then + tmp := ulimb + ulimb := vlimb + vlimb := tmp + end + if (ulimb |>> 16) > vlimb then + ulimb := ulimb \\ vlimb + if ulimb = 0 then + done := True + else + maybe := True + end + end + end + if not done then + from + until + ulimb = vlimb and not maybe + loop + if ulimb > vlimb or maybe then + if not maybe then + ulimb := ulimb - vlimb + end + from + if not maybe then + ulimb := ulimb |>> 1 + end + until + not maybe and ulimb.bit_test (0) + loop + if not maybe then + ulimb := ulimb |>> 1 + else + maybe := False + end + end + else + vlimb := vlimb - ulimb + from + vlimb := vlimb |>> 1 + until + vlimb.bit_test (0) + loop + vlimb := vlimb |>> 1 + end + end + end + end + Result := vlimb |<< zero_bits + end + + basic_gcd (gp: SPECIAL [NATURAL_32]; gp_offset: INTEGER; up_a: SPECIAL [NATURAL_32]; up_offset_a: INTEGER; usize_a: INTEGER; vp_a: SPECIAL [NATURAL_32]; vp_offset_a: INTEGER; vsize_a: INTEGER): INTEGER + require + usize_a >= 1 + vsize_a >= 1 + usize_a >= vsize_a + vp_a.valid_index (vp_offset_a) + vp_a.valid_index (vp_offset_a + vsize_a - 1) + up_a.valid_index (up_offset_a) + up_a.valid_index (up_offset_a + usize_a - 1) + vp_a [vp_offset_a].bit_test (0) + up_a [up_offset_a + usize_a - 1] /= 0 + vp_a [vp_offset_a + vsize_a - 1] /= 0 + local + orig_vp: SPECIAL [NATURAL_32] + orig_vp_offset: INTEGER + orig_vsize: INTEGER + binary_gcd_ctr: INTEGER + scratch: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + vbitsize: INTEGER + d: INTEGER + orig_up: SPECIAL [NATURAL_32] + orig_up_offset: INTEGER + orig_usize: INTEGER + anchor_up: SPECIAL [NATURAL_32] + anchor_up_offset: INTEGER + up: SPECIAL [NATURAL_32] + up_offset: INTEGER + usize: INTEGER + i: INTEGER + vp: SPECIAL [NATURAL_32] + vp_offset: INTEGER + vsize: INTEGER + r: INTEGER + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + junk: NATURAL_32 + bp0: NATURAL_32 + bp1: NATURAL_32 + cp0: NATURAL_32 + cp1: NATURAL_32 + u_inv: NATURAL_32 + hi: CELL [NATURAL_32] + lo: CELL [NATURAL_32] + v_inv: NATURAL_32 + c: NATURAL_32 + b: NATURAL_32 + rsize: INTEGER + done: BOOLEAN + continue: BOOLEAN + carry: CELL [NATURAL_32] + do + create carry.put (0) + create hi.put (0) + create lo.put (0) + up := up_a + up_offset := up_offset_a + usize := usize_a + vp := vp_a + vp_offset := vp_offset_a + vsize := vsize_a + orig_vp := vp + orig_vp_offset := vp_offset + orig_vsize := vsize + if vsize >= 5 then + orig_up := up + orig_up_offset := up_offset + orig_usize := usize + create anchor_up.make_filled (0, usize + 2) + anchor_up.copy_data (orig_up, orig_up_offset, anchor_up_offset, usize) + up := anchor_up + d := leading_zeros (up [up_offset + usize - 1]) + d := usize * limb_bits - d + vbitsize := leading_zeros (vp [vp_offset + vsize - 1]) + vbitsize := vsize * limb_bits - vbitsize + d := d - vbitsize + 1 + up [up_offset + usize] := 0 + usize := usize + 1 + junk := bdivmod (up, up_offset, up, up_offset, usize, vp, vp_offset, vsize, d) + d := d // limb_bits + up_offset := up_offset + d + usize := usize - d + from + until + usize = 0 or up [up_offset] /= 0 + loop + up_offset := up_offset + 1 + usize := usize - 1 + end + if usize = 0 then + done := True + else + create vp.make_filled (0, vsize + 2) + vp_offset := 0 + vp.copy_data (orig_vp, orig_vp_offset, 0, vsize) + from + until + usize = 0 + loop + if up [up_offset + usize - 1].bit_test (limb_high_bit) then + anchor_up [anchor_up_offset] := 0 - up [up_offset] + from + i := 1 + until + i >= usize + loop + anchor_up [anchor_up_offset + i] := up [up_offset + i].bit_not + i := i + 1 + end + up := anchor_up + up_offset := anchor_up_offset + end + usize := normalize (up, up_offset, usize) + if not up [up_offset].bit_test (0) then + r := trailing_zeros (up [up_offset]) + rshift (anchor_up, anchor_up_offset, up, up_offset, usize, r, carry) + junk := carry.item + usize := usize - (anchor_up [anchor_up_offset + usize - 1] = 0).to_integer + else + anchor_up.copy_data (up, up_offset, anchor_up_offset, usize) + end + tmp_special := anchor_up + anchor_up := vp + vp := tmp_special + tmp_integer := anchor_up_offset + anchor_up_offset := vp_offset + vp_offset := tmp_integer + tmp_integer := usize + usize := vsize + vsize := tmp_integer + up := anchor_up + up_offset := anchor_up_offset + if vsize <= 2 then + usize := 0 + else + d := vbitsize + vbitsize := leading_zeros (vp [vp_offset + vsize - 1]) + vbitsize := vsize * limb_bits - vbitsize + d := d - vbitsize + 1 + if d > 16 then + up [up_offset + usize] := 0 + usize := usize + 1 + junk := bdivmod (up, up_offset, up, up_offset, usize, vp, vp_offset, vsize, d) + d := d // limb_bits + up_offset := up_offset + d + usize := usize - d + else + u_inv := modlimb_invert (up [up_offset]) + cp0 := vp [vp_offset] * u_inv + umul_ppmm (hi, lo, cp0, up [up_offset]) + cp1 := (vp [vp_offset + 1] - hi.item - cp0 * up [up_offset + 1]) * u_inv + mul_1 (up, up_offset, up, up_offset, usize, find_a (cp0, cp1), carry) + up [up_offset + usize] := carry.item + usize := usize + 1 + v_inv := modlimb_invert (vp [vp_offset]) + bp0 := (up [up_offset] * v_inv) + umul_ppmm (hi, lo, bp0, vp [vp_offset]) + bp1 := (up [up_offset + 1] + hi.item + (bp0.bit_and (vp [vp_offset + 1]))).bit_and (0x1) + up [up_offset + usize] := 0 + usize := usize + 1 + if bp1 /= 0 then + addmul_1 (up, up_offset, vp, vp_offset, vsize, 0 - bp0, carry) + c := carry.item + add_1 (up, up_offset + vsize, up, up_offset + vsize, usize - vsize, c, carry) + junk := carry.item + else + submul_1 (up, up_offset, vp, vp_offset, vsize, bp0, carry) + b := carry.item + sub_1 (up, up_offset + vsize, up, up_offset + vsize, usize - vsize, b, carry) + junk := carry.item + end + up_offset := up_offset + 2 + usize := usize - 2 + end + from + until + usize = 0 or up [up_offset] /= 0 + loop + up_offset := up_offset + 1 + usize := usize - 1 + end + end + end + up := orig_up + up_offset := orig_up_offset + usize := orig_usize + binary_gcd_ctr := 2 + end + else + binary_gcd_ctr := 1 + end + if not done then + scratch := (2 * vsize).max (vsize + 1) + if usize + 1 > scratch then + scratch := usize + 1 + end + create tp.make_filled (0, scratch) + tp_offset := 0 + from + until + binary_gcd_ctr = 0 + loop + continue := False + binary_gcd_ctr := binary_gcd_ctr - 1 + if usize > vsize then + tdiv_qr (tp, tp_offset + vsize, tp, tp_offset, up, up_offset, usize, vp, vp_offset, vsize) + rsize := vsize + rsize := normalize (tp, tp_offset, rsize) + if rsize = 0 then + continue := True + else + up.copy_data (tp, tp_offset, up_offset, vsize) + end + end + if not continue then + vsize := ngcd_lehmer (vp, vp_offset, up, up_offset, vp, vp_offset, vsize, tp, tp_offset) + end + up := orig_vp + up_offset := orig_vp_offset + usize := orig_vsize + end + end + if vp /= gp then + gp.copy_data (vp, vp_offset, gp_offset, vsize) + end + Result := vsize + ensure + Result > 0 + Result <= usize_a + Result <= vsize_a + end + + ngcd_matrix1_vector (m: SPECIAL [NATURAL_32]; n_a: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; bp: SPECIAL [NATURAL_32]; bp_offset: INTEGER; tp: SPECIAL [NATURAL_32]; tp_offset: INTEGER): INTEGER + local + h0: NATURAL_32 + h1: NATURAL_32 + n: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + n := n_a + tp.copy_data (ap, ap_offset, tp_offset, n) + mul_1 (ap, ap_offset, ap, ap_offset, n, m [3], carry) + h0 := carry.item + submul_1 (ap, ap_offset, bp, bp_offset, n, m [1], carry) + h1 := carry.item + mul_1 (bp, bp_offset, bp, bp_offset, n, m [0], carry) + h0 := carry.item + submul_1 (bp, bp_offset, tp, tp_offset, n, m [2], carry) + h1 := carry.item + n := n - (ap [ap_offset + n - 1].bit_or (bp [bp_offset + n - 1]) = 0).to_integer + Result := n + end + + ngcd_subdiv_step (gp: SPECIAL [NATURAL_32]; gp_offset: INTEGER; gn: TUPLE [gn: INTEGER]; ap_a: SPECIAL [NATURAL_32]; ap_offset_a: INTEGER; bp_a: SPECIAL [NATURAL_32]; bp_offset_a: INTEGER; n: INTEGER; tp: SPECIAL [NATURAL_32]; tp_offset: INTEGER): INTEGER + local + an: INTEGER + bn: INTEGER + ap: SPECIAL [NATURAL_32] + ap_offset: INTEGER + bp: SPECIAL [NATURAL_32] + bp_offset: INTEGER + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + junk: NATURAL_32 + c: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + ap := ap_a + ap_offset := ap_offset_a + bp := bp_a + bp_offset := bp_offset_a + from + an := n + until + an <= 0 or else ap [ap_offset + an - 1] /= bp [bp_offset + an - 1] + loop + an := an - 1 + end + if an = 0 then + gp.copy_data (ap, ap_offset, gp_offset, n) + gn.gn := n + Result := 0 + else + if ap [ap_offset + an - 1] < bp [bp_offset + an - 1] then + tmp_special := ap + ap := bp + bp := tmp_special + tmp_integer := ap_offset + ap_offset := bp_offset + bp_offset := tmp_integer + bn := n + bn := normalize (bp, bp_offset, bn) + if bn = 0 then + gp.copy_data (ap, ap_offset, gp_offset, n) + gn.gn := n + Result := 0 + else + sub_n (ap, ap_offset, ap, ap_offset, bp, bp_offset, an, carry) + junk := carry.item + an := normalize (ap, ap_offset, an) + if an < bn then + tmp_special := ap + ap := bp + bp := tmp_special + tmp_integer := ap_offset + ap_offset := bp_offset + bp_offset := tmp_integer + tmp_integer := an + an := bn + bn := tmp_integer + elseif an = bn then + c := cmp (ap, ap_offset, bp, bp_offset, an) + if c < 0 then + tmp_special := ap + ap := bp + bp := tmp_special + tmp_integer := ap_offset + ap_offset := bp_offset + bp_offset := tmp_integer + end + end + tdiv_qr (tp, tp_offset + bn, tp, tp_offset, ap, ap_offset, an, bp, bp_offset, bn) + an := bn + an := normalize (tp, tp_offset, an) + if an = 0 then + gp.copy_data (bp, bp_offset, gp_offset, bn) + gn.gn := bn + Result := 0 + else + ap.copy_data (tp, tp_offset, ap_offset, bn) + Result := bn + end + end + end + end + end + + nhgcd2 (ah_a: NATURAL_32; al_a: NATURAL_32; bh_a: NATURAL_32; bl_a: NATURAL_32; m: SPECIAL [NATURAL_32]): BOOLEAN + local + u00: NATURAL_32 + u01: NATURAL_32 + u10: NATURAL_32 + u11: NATURAL_32 + al: CELL [NATURAL_32] + ah: CELL [NATURAL_32] + bl: CELL [NATURAL_32] + bh: CELL [NATURAL_32] + done: BOOLEAN + subtract_a: BOOLEAN + r0: CELL [NATURAL_32] + r1: CELL [NATURAL_32] + q: NATURAL_32 + do + create r0.put (0) + create r1.put (0) + create al.put (al_a) + create ah.put (ah_a) + create bl.put (bl_a) + create bh.put (bh_a) + if ah.item < 2 or bh.item < 2 then + Result := False + else + if ah.item > bh.item or (ah.item = bh.item and al.item > bl.item) then + sub_ddmmss (ah, al, ah.item, al.item, bh.item, bl.item) + if ah.item < 2 then + Result := False + done := True + else + u11 := 1 + u01 := u11 + u00 := u01 + u10 := 0 + end + else + sub_ddmmss (bh, bl, bh.item, bl.item, ah.item, al.item) + if bh.item < 2 then + Result := False + done := True + else + u11 := 1 + u10 := u11 + u00 := u10 + u01 := 0 + end + end + if not done then + if ah.item < bh.item then + subtract_a := True + end + from + until + not subtract_a and done + loop + if not subtract_a then + if ah.item = bh.item then + done := True + else + sub_ddmmss (ah, al, ah.item, al.item, bh.item, bl.item) + if ah.item < 2 then + done := True + else + if ah.item <= bh.item then + u01 := u01 + u00 + u11 := u11 + u10 + else + q := div2 (r0, r1, ah.item, al.item, bh.item, bl.item) + al.put (r0.item) + ah.put (r1.item) + if ah.item < 2 then + u01 := u01 + q * u00 + u11 := u11 + q * u10 + done := True + else + q := q + 1 + u01 := u01 + q * u00 + u11 := u11 + q * u10 + end + end + end + end + end + if not done then + subtract_a := False + if ah.item = bh.item then + done := True + else + sub_ddmmss (bh, bl, bh.item, bl.item, ah.item, al.item) + if bh.item < 2 then + done := True + else + if bh.item <= ah.item then + u00 := u00 + u01 + u10 := u10 + u11 + else + q := div2 (r0, r1, bh.item, bl.item, ah.item, al.item) + bl.put (r0.item) + bh.put (r1.item) + if bh.item < 2 then + u00 := u00 + q * u01 + u10 := u10 + q * u11 + done := True + else + q := q + 1 + u00 := u00 + q * u01 + u10 := u10 + q * u11 + end + end + end + end + end + end + m [0] := u00 + m [1] := u01 + m [2] := u10 + m [3] := u11 + Result := True + end + end + end + + div2 (r0: CELL [NATURAL_32]; r1: CELL [NATURAL_32]; nh_a: NATURAL_32; nl_a: NATURAL_32; dh_a: NATURAL_32; dl_a: NATURAL_32): NATURAL_32 + require + dh_a /= 0 or dl_a /= 0 + local + q: NATURAL_32 + count: INTEGER_32 + dh: NATURAL_32 + dl: NATURAL_32 + nh: CELL [NATURAL_32] + nl: CELL [NATURAL_32] + do + create nh.put (0) + create nl.put (0) + nh.put (nh_a) + nl.put (nl_a) + dh := dh_a + dl := dl_a + if nh.item.bit_test (limb_high_bit) then + from + count := 1 + invariant + dh /= 0 or dl /= 0 + until + dh.bit_test (limb_high_bit) + loop + dh := (dh |<< 1).bit_or (dl |>> (limb_bits - 1)) + dl := (dl |<< 1) + count := count + 1 + end + from + until + count = 0 + loop + q := q |<< 1 + if nh.item > dh or (nh.item = dh and nl.item >= dl) then + sub_ddmmss (nh, nl, nh.item, nl.item, dh, dl) + q := q.bit_or (1) + end + dl := (dh |<< (limb_bits - 1)).bit_or (dl |>> 1) + dh := dh |>> 1 + count := count - 1 + end + else + from + until + not (nh.item > dh or (nh.item = dh and nl.item >= dl)) + loop + dh := (dh |<< 1).bit_or (dl |>> (limb_bits - 1)) + dl := dl |<< 1 + count := count + 1 + end + from + until + count = 0 + loop + dl := (dh |<< (limb_bits - 1)).bit_or (dl |>> 1) + dh := dh |>> 1 + q := q |<< 1 + if nh.item > dh or (nh.item = dh and nl.item >= dl) then + sub_ddmmss (nh, nl, nh.item, nl.item, dh, dl) + q := q.bit_or (1) + end + count := count - 1 + end + end + r0.put (nl.item) + r1.put (nh.item) + Result := q + end + + mul_2 (rp: SPECIAL [NATURAL_32]; rp_offset: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; n: INTEGER; bp: SPECIAL [NATURAL_32]; bp_offset: INTEGER) + local + bh: NATURAL_32 + bl: NATURAL_32 + cy: NATURAL_32 + hi: CELL [NATURAL_32] + lo: CELL [NATURAL_32] + sh: CELL [NATURAL_32] + sl: CELL [NATURAL_32] + th: CELL [NATURAL_32] + tl: CELL [NATURAL_32] + i: INTEGER + do + create hi.put (0) + create lo.put (0) + create sh.put (0) + create sl.put (0) + create tl.put (0) + create th.put (0) + bl := bp [bp_offset] + umul_ppmm (hi, lo, bl, ap [ap_offset]) + rp [rp_offset] := lo.item + bh := bp [bp_offset + 1] + from + i := 1 + cy := 0 + until + i >= n + loop + umul_ppmm (sh, sl, bh, ap [ap_offset + i - 1]) + umul_ppmm (th, tl, bl, ap [ap_offset + i]) + add_ssaaaa (sh, sl, sh.item, sl.item, cy, hi.item) + add_ssaaaa (hi, lo, th.item, tl.item, sh.item, sl.item) + rp [rp_offset + i] := lo.item + cy := (hi.item < th.item).to_integer.to_natural_32 + i := i + 1 + end + umul_ppmm (sh, sl, bh, ap [ap_offset + n - 1]) + add_ssaaaa (hi, lo, sh.item, sl.item, cy, hi.item) + rp [rp_offset + n + 1] := hi.item + rp [rp_offset + n] := lo.item + end + + ngcd_matrix1_adjust (m: SPECIAL [NATURAL_32]; n_a: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; bp: SPECIAL [NATURAL_32]; bp_offset: INTEGER; p: INTEGER; tp: SPECIAL [NATURAL_32]; tp_offset: INTEGER): INTEGER + local + ah: NATURAL_32 + bh: NATURAL_32 + cy: NATURAL_32 + n: INTEGER + carry: CELL [NATURAL_32] + do + create carry.put (0) + n := n_a + tp.copy_data (ap, ap_offset, tp_offset, p) + mul_1 (ap, ap_offset, ap, ap_offset, p, m [3], carry) + ah := carry.item + submul_1 (ap, ap_offset, bp, bp_offset, p, m [1], carry) + cy := carry.item + if cy > ah then + decr_u (ap, ap_offset + p, cy - ah) + ah := 0 + else + ah := ah - cy + if ah > 0 then + add_1 (ap, ap_offset + p, ap, ap_offset + p, n, ah, carry) + ah := carry.item + end + end + mul_1 (bp, bp_offset, bp, bp_offset, p, m [0], carry) + bh := carry.item + submul_1 (bp, bp_offset, tp, tp_offset, p, m [2], carry) + cy := carry.item + if cy > bh then + decr_u (bp, bp_offset + p, cy - bh) + bh := 0 + else + bh := bh - cy + if bh > 0 then + add_1 (bp, bp_offset + p, bp, bp_offset + p, n, bh, carry) + bh := carry.item + end + end + n := n + p + if ah > 0 or bh > 0 then + ap [ap_offset + n] := ah + bp [bp_offset + n] := bh + n := n + 1 + else + if ap [ap_offset + n - 1] = 0 and bp [bp_offset + n - 1] = 0 then + n := n - 1 + end + end + Result := n + end + + ngcd_matrix2_adjust (m: SPECIAL [NATURAL_32]; n_a: INTEGER; ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; bp: SPECIAL [NATURAL_32]; bp_offset: INTEGER; p: INTEGER; tp: SPECIAL [NATURAL_32]; tp_offset: INTEGER): INTEGER + local + t0: SPECIAL [NATURAL_32] + t0_offset: INTEGER + t1: SPECIAL [NATURAL_32] + t1_offset: INTEGER + ah: NATURAL_32 + bh: NATURAL_32 + cy: NATURAL_32 + n: INTEGER + junk: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + n := n_a + t0 := tp + t0_offset := tp_offset + t1 := tp + t1_offset := tp_offset + p + 2 + mul_2 (t0, t0_offset, ap, ap_offset, p, m, 3) + mul_2 (t1, t1_offset, ap, ap_offset, p, m, 2) + ap.copy_data (t0, t0_offset, ap_offset, p) + add (ap, ap_offset + p, ap, ap_offset + p, n, t0, t0_offset + p, 2, carry) + ah := carry.item + mul (t0, t0_offset, bp, bp_offset, p, m, 1, 2, carry) + junk := carry.item + sub (ap, ap_offset, ap, ap_offset, n + p, t0, t0_offset, p + 2, carry) + cy := carry.item + ah := ah - cy + mul (t0, t0_offset, bp, bp_offset, p, m, 0, 2, carry) + junk := carry.item + bp.copy_data (t0, t0_offset, bp_offset, p) + add (bp, bp_offset + p, bp, bp_offset + p, n, t0, t0_offset + p, 2, carry) + bh := carry.item + sub (bp, bp_offset, bp, bp_offset, n + p, t1, t1_offset, p + 2, carry) + cy := carry.item + bh := bh - cy + n := n + p + if ah > 0 or bh > 0 then + ap [ap_offset + n] := ah + bp [bp_offset + n] := bh + n := n + 1 + else + if ap [ap_offset + n - 1] = 0 and bp [bp_offset + n - 1] = 0 then + n := n - 1 + end + end + Result := n + end + + ngcd_lehmer (gp: SPECIAL [NATURAL_32]; gp_offset: INTEGER; ap_a: SPECIAL [NATURAL_32]; ap_offset_a: INTEGER; bp_a: SPECIAL [NATURAL_32]; bp_offset_a: INTEGER; n_a: INTEGER; tp: SPECIAL [NATURAL_32]; tp_offset: INTEGER): INTEGER + local + gn: TUPLE [gn: INTEGER] + n: INTEGER + m1: SPECIAL [NATURAL_32] + m2: SPECIAL [NATURAL_32] + p: INTEGER + res: TUPLE [res: INTEGER] + nn: INTEGER + m: SPECIAL [NATURAL_32] + ah: NATURAL_32 + al: NATURAL_32 + bh: NATURAL_32 + bl: NATURAL_32 + mask: NATURAL_32 + shift: INTEGER + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + r: INTEGER + ap: SPECIAL [NATURAL_32] + ap_offset: INTEGER + bp: SPECIAL [NATURAL_32] + bp_offset: INTEGER + done: BOOLEAN + do + ap := ap_a + ap_offset := ap_offset_a + bp := bp_a + bp_offset := bp_offset_a + create gn + create res + n := n_a + create m1.make_filled (0, 4) + create m2.make_filled (0, 4) + create m.make_filled (0, 4) + from + until + n < 7 + loop + p := n - 5 + nn := nhgcd5 (ap, ap_offset + p, bp, bp_offset + p, res, m1, m2) + inspect res.res + when 0 then + n := ngcd_subdiv_step (gp, gp_offset, gn, ap, ap_offset, bp, bp_offset, n, tp, tp_offset) + when 1 then + n := ngcd_matrix1_adjust (m1, nn, ap, ap_offset, bp, bp_offset, p, tp, tp_offset) + when 2 then + n := ngcd_matrix2_adjust (m2, nn, ap, ap_offset, bp, bp_offset, p, tp, tp_offset) + end + end + from + until + n <= 2 or done + loop + mask := ap [ap_offset + n - 1].bit_or (bp [bp_offset + n - 1]) + if mask.bit_test (limb_high_bit) then + ah := ap [ap_offset + n - 1] + al := ap [ap_offset + n - 2] + bh := bp [bp_offset + n - 1] + bl := bp [bp_offset + n - 2] + else + shift := leading_zeros (mask) + ah := extract_limb (shift, ap [ap_offset + n - 1], ap [ap_offset + n - 2]) + al := extract_limb (shift, ap [ap_offset + n - 2], ap [ap_offset + n - 3]) + bh := extract_limb (shift, bp [bp_offset + n - 1], bp [bp_offset + n - 2]) + bl := extract_limb (shift, bp [bp_offset + n - 2], bp [bp_offset + n - 3]) + end + if nhgcd2 (ah, al, bh, bl, m) then + n := ngcd_matrix1_vector (m, n, ap, ap_offset, bp, bp_offset, tp, tp_offset) + else + n := ngcd_subdiv_step (gp, gp_offset, gn, ap, ap_offset, bp, bp_offset, n, tp, tp_offset) + if n = 0 then + Result := gn.gn + done := True + end + end + end + if not done then + if n = 1 then + gp [gp_offset] := gcd_1 (ap, ap_offset, 1, bp [bp_offset]) + Result := 1 + else + if not ap [ap_offset].bit_test (0) then + tmp_special := ap + ap := bp + bp := tmp_special + tmp_integer := ap_offset + ap_offset := bp_offset + bp_offset := tmp_integer + end + if bp [bp_offset] = 0 then + gp [gp_offset] := gcd_1 (ap, ap_offset, 2, bp [bp_offset + 1]) + Result := 1 + else + if not bp [bp_offset].bit_test (0) then + r := trailing_zeros (bp [bp_offset]) + bp [bp_offset] := (bp [bp_offset + 1] |<< (limb_bits - r)).bit_or (bp [bp_offset] |>> r) + bp [bp_offset + 1] := bp [bp_offset + 1] |>> r + end + n := gcd_2 (ap, ap_offset, bp, bp_offset) + gp.copy_data (ap, ap_offset, gp_offset, n) + Result := n + end + end + end + ensure + Result > 0 + Result <= n_a + end + + nhgcd5 (ap: SPECIAL [NATURAL_32]; ap_offset: INTEGER; bp: SPECIAL [NATURAL_32]; bp_offset: INTEGER; res: TUPLE [res: INTEGER]; m1: SPECIAL [NATURAL_32]; m: SPECIAL [NATURAL_32]): INTEGER_32 + local + m2: SPECIAL [NATURAL_32] + t: SPECIAL [NATURAL_32] + n: INTEGER + ah: NATURAL_32 + al: NATURAL_32 + bh: NATURAL_32 + bl: NATURAL_32 + mask: NATURAL_32 + shift: INTEGER + ph: CELL [NATURAL_32] + pl: CELL [NATURAL_32] + do + create ph.put (0) + create pl.put (0) + create t.make_filled (0, 5) + create m2.make_filled (0, 4) + mask := ap [ap_offset + 4].bit_or (bp [bp_offset + 4]) + if mask.bit_test (31) then + ah := ap [ap_offset + 4] + al := ap [ap_offset + 3] + bh := bp [bp_offset + 4] + bl := bp [bp_offset + 3] + else + shift := leading_zeros (mask) + ah := extract_limb (shift, ap [ap_offset + 4], ap [ap_offset + 3]) + al := extract_limb (shift, ap [ap_offset + 3], ap [ap_offset + 2]) + bh := extract_limb (shift, bp [bp_offset + 4], bp [bp_offset + 3]) + bl := extract_limb (shift, bp [bp_offset + 3], bp [bp_offset + 2]) + end + if nhgcd2 (ah, al, bh, bl, m1) then + res.res := 0 + Result := 0 + else + n := ngcd_matrix1_vector (m1, 5, ap, ap_offset, bp, bp_offset, t, 0) + mask := ap [ap_offset + n - 1].bit_or (bp [bp_offset + n - 1]) + if mask.bit_test (31) then + ah := ap [ap_offset + n - 1] + al := ap [ap_offset + n - 2] + bh := bp [bp_offset + n - 1] + bl := bp [bp_offset + n - 2] + else + shift := leading_zeros (mask) + ah := extract_limb (shift, ap [ap_offset + n - 1], ap [ap_offset + n - 2]) + al := extract_limb (shift, ap [ap_offset + n - 2], ap [ap_offset + n - 3]) + bh := extract_limb (shift, bp [bp_offset + n - 1], bp [bp_offset + n - 2]) + bl := extract_limb (shift, bp [bp_offset + n - 2], bp [bp_offset + n - 3]) + end + if not nhgcd2 (ah, al, bh, bl, m2) then + res.res := 1 + Result := n + else + n := ngcd_matrix1_vector (m2, n, ap, ap_offset, bp, bp_offset, t, 0) + dotmul_ppxxyy (ph, pl, m1 [0], m1 [1], m2 [0], m2 [2]) + m [1] := ph.item + m [0] := pl.item + dotmul_ppxxyy (ph, pl, m1 [0], m1 [1], m2 [1], m2 [3]) + m [3] := ph.item + m [2] := pl.item + dotmul_ppxxyy (ph, pl, m1 [2], m1 [3], m2 [0], m2 [2]) + m [5] := ph.item + m [4] := pl.item + dotmul_ppxxyy (ph, pl, m1 [2], m1 [3], m2 [1], m2 [3]) + m [7] := ph.item + m [6] := pl.item + res.res := 2 + Result := n + end + end + end + + dotmul_ppxxyy (ph: CELL [NATURAL_32]; pl: CELL [NATURAL_32]; x1: NATURAL_32; x2: NATURAL_32; y1: NATURAL_32; y2: NATURAL_32) + local + dotmul_sh: CELL [NATURAL_32] + dotmul_sl: CELL [NATURAL_32] + dotmul_th: CELL [NATURAL_32] + dotmul_tl: CELL [NATURAL_32] + sh: CELL [NATURAL_32] + sl: CELL [NATURAL_32] + do + create dotmul_sh.put (0) + create dotmul_sl.put (0) + create dotmul_th.put (0) + create dotmul_tl.put (0) + create sh.put (0) + create sl.put (0) + + umul_ppmm (dotmul_sh, dotmul_sl, x1, y1) + umul_ppmm (dotmul_th, dotmul_tl, x2, y2) + add_ssaaaa (sh, sl, dotmul_sh.item, dotmul_sl.item, dotmul_th.item, dotmul_tl.item) + ph.put (sh.item) + pl.put (sl.item) + end +end diff --git a/library/crypto/eapml/facilities/special_logic.e b/library/crypto/eapml/facilities/special_logic.e new file mode 100644 index 00000000..30e437ea --- /dev/null +++ b/library/crypto/eapml/facilities/special_logic.e @@ -0,0 +1,332 @@ +note + description: "Summary description for {NUMBER_LOGIC}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "It is a free market that makes monopolies impossible. - Ayn Rand" + +deferred class + SPECIAL_LOGIC + +inherit + LIMB_MANIPULATION + +feature + + com_n (target: SPECIAL [NATURAL_32]; target_offset_a: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER; op1_count_a: INTEGER) + require + op1_count_a >= 1 + local + target_offset: INTEGER + op1_offset: INTEGER + op1_count: INTEGER + do + target_offset := target_offset_a + op1_offset := op1_offset_a + op1_count := op1_count_a + from + until + op1_count = 0 + loop + target [target_offset] := op1 [op1_offset].bit_not + target_offset := target_offset + 1 + op1_offset := op1_offset + 1 + op1_count := op1_count - 1 + end + end + + hamdist (op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset_a: INTEGER; n_a: INTEGER): INTEGER + local + p0: NATURAL_32 + p1: NATURAL_32 + p2: NATURAL_32 + p3: NATURAL_32 + x: NATURAL_32 + p01: NATURAL_32 + p23: NATURAL_32 + i: INTEGER + op1_offset: INTEGER + n: INTEGER + op2_offset: INTEGER + do + op2_offset := op2_offset_a + n := n_a + op1_offset := op1_offset_a + from + i := n |>> 2 + until + i = 0 + loop + p0 := op1 [op1_offset].bit_xor (op2 [op2_offset]) + p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3) + p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5) + + p1 := op1 [op1_offset + 1].bit_xor (op2 [op2_offset + 1]) + p1 := p1 - (p1 |>> 1).bit_and (limb_max // 3) + p1 := (p1 |>> 2).bit_and (limb_max // 5) + p1.bit_and (limb_max // 5) + + p01 := p0 + p1 + p01 := (p01 |>> 4).bit_and (limb_max // 17) + p01.bit_and (limb_max // 17) + + p2 := op1 [op1_offset + 2].bit_xor (op2 [op2_offset + 2]) + p2 := p2 - (p2 |>> 1).bit_and (limb_max // 3) + p2 := (p2 |>> 2).bit_and (limb_max // 5) + p2.bit_and (limb_max // 5) + + p3 := op1 [op1_offset + 3].bit_xor (op2 [op2_offset + 3]) + p3 := p3 - (p3 |>> 1).bit_and (limb_max // 3) + p3 := (p3 |>> 2).bit_and (limb_max // 5) + p3.bit_and (limb_max // 5) + + p23 := p2 + p3 + p23 := (p23 |>> 4).bit_and (limb_max // 17) + p23.bit_and (limb_max // 17) + + x := p01 + p23 + x := (x |>> 8) + x + x := (x |>> 16) + x + Result := Result + x.bit_and (0xff).to_integer_32 + op1_offset := op1_offset + 4 + op2_offset := op2_offset + 4 + i := i - 1 + end + n := n.bit_and (3) + if n /= 0 then + x := 0 + from + until + n = 0 + loop + p0 := op1 [op1_offset].bit_xor (op2 [op2_offset]) + p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3) + p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5) + p0 := ((p0 |>> 4) | p0).bit_and (limb_max // 17) + x := x + p0 + op1_offset := op1_offset + 1 + op2_offset := op2_offset + 1 + n := n - 1 + end + x := (x |>> 8) + x + x := (x |>> 16) + x + Result := Result + x.bit_and (0xff).to_integer_32 + end + end + + lshift (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; count: INTEGER_32; carry: CELL [NATURAL_32]) + require + target.valid_index (target_offset) + target.valid_index (target_offset + n - 1) + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + n - 1) + count > 0 + count < 32 + local + high_limb: NATURAL_32 + low_limb: NATURAL_32 + tnc: INTEGER_32 + i: INTEGER_32 + up: INTEGER_32 + rp: INTEGER_32 + do + up := op1_offset + n + rp := target_offset + n + tnc := 32 - count + up := up - 1 + low_limb := op1 [up] + carry.put (low_limb |>> tnc) + high_limb := low_limb |<< count + from + i := n - 1 + until + i = 0 + loop + up := up - 1 + low_limb := op1 [up] + rp := rp - 1 + target [rp] := high_limb.bit_or (low_limb |>> tnc) + high_limb := low_limb |<< count + i := i - 1 + end + rp := rp - 1 + target [rp] := high_limb + end + + rshift (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; n: INTEGER_32; count: INTEGER_32; carry: CELL [NATURAL_32]) + local + high_limb: NATURAL_32 + low_limb: NATURAL_32 + tnc: INTEGER_32 + i: INTEGER_32 + op1_cursor: INTEGER_32 + target_cursor: INTEGER_32 + do + tnc := 32 - count + op1_cursor := op1_offset + high_limb := op1 [op1_cursor] + op1_cursor := op1_cursor + 1 + carry.put (high_limb |<< tnc) + low_limb := high_limb |>> count + from + i := n - 1 + until + i = 0 + loop + high_limb := op1 [op1_cursor] + op1_cursor := op1_cursor + 1 + target [target_cursor] := low_limb.bit_or (high_limb |<< tnc) + target_cursor := target_cursor + 1 + low_limb := high_limb |>> count + i := i - 1 + end + target [target_cursor] := low_limb + end + + popcount (op1: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER; n_a: INTEGER): INTEGER + local + p0: NATURAL_32 + p1: NATURAL_32 + p2: NATURAL_32 + p3: NATURAL_32 + x: NATURAL_32 + p01: NATURAL_32 + p23: NATURAL_32 + i: INTEGER + op1_offset: INTEGER + n: INTEGER + do + n := n_a + op1_offset := op1_offset_a + from + i := n |>> 2 + until + i = 0 + loop + p0 := op1 [op1_offset] + p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3) + p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5) + + p1 := op1 [op1_offset + 1] + p1 := p1 - (p1 |>> 1).bit_and (limb_max // 3) + p1 := (p1 |>> 2).bit_and (limb_max // 5) + p1.bit_and (limb_max // 5) + + p01 := p0 + p1 + p01 := (p01 |>> 4).bit_and (limb_max // 17) + p01.bit_and (limb_max // 17) + + p2 := op1 [op1_offset + 2] + p2 := p2 - (p2 |>> 1).bit_and (limb_max // 3) + p2 := (p2 |>> 2).bit_and (limb_max // 5) + p2.bit_and (limb_max // 5) + + p3 := op1 [op1_offset + 3] + p3 := p3 - (p3 |>> 1).bit_and (limb_max // 3) + p3 := (p3 |>> 2).bit_and (limb_max // 5) + p3.bit_and (limb_max // 5) + + p23 := p2 + p3 + p23 := (p23 |>> 4).bit_and (limb_max // 17) + p23.bit_and (limb_max // 17) + + x := p01 + p23 + x := (x |>> 8) + x + x := (x |>> 16) + x + Result := Result + x.bit_and (0xff).to_integer_32 + op1_offset := op1_offset + 4 + i := i - 1 + end + n := n.bit_and (3) + if n /= 0 then + x := 0 + from + until + n = 0 + loop + p0 := op1 [op1_offset] + p0 := p0 - (p0 |>> 1).bit_and (limb_max // 3) + p0 := (p0 |>> 2).bit_and (limb_max // 5) + p0.bit_and (limb_max // 5) + p0 := ((p0 |>> 4) | p0).bit_and (limb_max // 17) + x := x + p0 + op1_offset := op1_offset + 1 + n := n - 1 + end + x := (x |>> 8) + x + x := (x |>> 16) + x + Result := Result + x.bit_and (0xff).to_integer_32 + end + end + + bit_xor_lshift (target: SPECIAL [NATURAL_32] target_offset: INTEGER op1: SPECIAL [NATURAL_32] op1_offset: INTEGER op1_count: INTEGER op2: SPECIAL [NATURAL_32] op2_offset: INTEGER op2_count: INTEGER op2_lshift: INTEGER) + require + op2_lshift >= 0 + op1 /= op2 + target /= op2 + op1_count = 0 or op1.valid_index (op1_offset) + op1_count = 0 or op1.valid_index (op1_offset + op1_count - 1) + op2_count = 0 or op2.valid_index (op2_offset) + op2_count = 0 or op2.valid_index (op2_offset + op2_count - 1) + (op1_count = 0 and op2_count = 0) or target.valid_index (target_offset) + (op1_count = 0 and op2_count = 0) or target.valid_index (target_offset + op1_count.max (op2_count + bits_to_limbs (op2_lshift)) - 1) + local + op2_limb_high: NATURAL_32 + op2_limb_low: NATURAL_32 + op2_limb: NATURAL_32 + cursor: INTEGER + shift_limbs: INTEGER + shift_bits: INTEGER + do + shift_limbs := op2_lshift // limb_bits + shift_bits := op2_lshift \\ limb_bits + target.copy_data (op1, op1_offset, target_offset, shift_limbs) + from + until + cursor >= op2_count or cursor >= op1_count - shift_limbs + loop + op2_limb_low := op2_limb_high + op2_limb_high := op2 [op2_offset + cursor] + op2_limb := extract_limb (shift_bits, op2_limb_high, op2_limb_low) + target [target_offset + shift_limbs + cursor] := op2_limb.bit_xor (op1 [op1_offset + shift_limbs + cursor]) + cursor := cursor + 1 + end + if cursor >= op2_count then + op2_limb_low := op2_limb_high + op2_limb := extract_limb (shift_bits, 0, op2_limb_low) + if cursor >= op1_count - shift_limbs then + target [target_offset + shift_limbs + cursor] := op2_limb + else + target [target_offset + shift_limbs + cursor] := op2_limb.bit_xor (op1 [op1_offset + shift_limbs + cursor]) + cursor := cursor + 1 + target.copy_data (op1, op1_offset + shift_limbs + cursor, target_offset + shift_limbs + cursor, op1_count - cursor - shift_limbs) + end + else + from + until + cursor >= op2_count + loop + op2_limb_low := op2_limb_high + op2_limb_high := op2 [op2_offset + cursor] + op2_limb := extract_limb (shift_bits, op2_limb_high, op2_limb_low) + target [target_offset + shift_limbs + cursor] := op2_limb + cursor := cursor + 1 + end + op2_limb_low := op2_limb_high + op2_limb := extract_limb (shift_bits, 0, op2_limb_low) + target [target_offset + shift_limbs + cursor] := op2_limb + end + end + + bit_xor (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER; op2_count: INTEGER) + require + (op1_count = 0 and op2_count = 0) or target.valid_index (target_offset) + (op1_count = 0 and op2_count = 0) or target.valid_index (target_offset + op1_count.max (op2_count) - 1) + local + cursor: INTEGER + min: INTEGER + do + from + min := op1_count.min (op2_count) + until + cursor >= min + loop + target [target_offset + cursor] := op1 [op1_offset + cursor].bit_xor (op2 [op2_offset + cursor]) + cursor := cursor + 1 + end + if op1_count > op2_count then + target.copy_data (op1, op1_offset + cursor, target_offset + cursor, op1_count - cursor) + elseif op2_count > op1_count then + target.copy_data (op2, op2_offset + cursor, target_offset + cursor, op2_count - cursor) + end + end +end diff --git a/library/crypto/eapml/facilities/special_number_theoretic.e b/library/crypto/eapml/facilities/special_number_theoretic.e new file mode 100644 index 00000000..52f99182 --- /dev/null +++ b/library/crypto/eapml/facilities/special_number_theoretic.e @@ -0,0 +1,849 @@ +note + description: "Summary description for {NUMBER_NUMBER_THEORETIC}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The best argument against democracy is a five-minute conversation with the average voter. - Winston Churchill" + +deferred class + SPECIAL_NUMBER_THEORETIC + +inherit + SPECIAL_DIVISION + SPECIAL_UTILITY + SPECIAL_LOGIC + LIMB_MANIPULATION + +feature + + gcdext_div2 (n1_a: NATURAL_32; n0_a: NATURAL_32; d1_a: NATURAL_32; d0_a: NATURAL_32): NATURAL_32 + require + d1_a /= 0 or d0_a /= 0 + local + q: NATURAL_32 + count: INTEGER + d1: NATURAL_32 + d0: NATURAL_32 + n1: CELL [NATURAL_32] + n0: CELL [NATURAL_32] + do + create n1.put (n1_a) + create n0.put (n0_a) + d1 := d1_a + d0 := d0_a + if n1.item.bit_test (limb_high_bit) then + from + count := 1 + invariant + d1 /= 0 or d0 /= 0 + until + d1.bit_test (limb_high_bit) + loop + d1 := (d1 |<< 1).bit_or (d0 |>> (limb_bits - 1)) + d0 := d0 |<< 1 + count := count + 1 + end + q := 0 + from + until + count = 0 + loop + q := q |<< 1 + if n1.item > d1 or (n1.item = d1 and n0.item >= d0) then + sub_ddmmss (n1, n0, n1.item, n0.item, d1, d0) + q := q.bit_or (1) + end + d0 := (d1 |<< (limb_bits - 1)).bit_or (d0 |>> 1) + d1 := d1 |>> 1 + count := count - 1 + end + Result := q + else + from + count := 0 + until + n1.item <= d1 and (n1.item /= d1 or n0.item < d0) + loop + d1 := (d1 |<< 1).bit_or (d0 |>> (limb_bits - 1)) + d0 := d0 |<< 1 + count := count + 1 + end + q := 0 + from + until + count = 0 + loop + d0 := (d1 |<< (limb_bits - 1)).bit_or (d0 |>> 1) + d1 := d1 |>> 1 + q := q |<< 1 + if n1.item > d1 or (n1.item = d1 and n0.item >= d0) then + sub_ddmmss (n1, n0, n1.item, n0.item, d1, d0) + q := q.bit_or (1) + end + count := count - 1 + end + Result := q + end + end + + basic_gcdext (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; cofactor: SPECIAL [NATURAL_32]; cofactor_offset: INTEGER_32; cofactor_count: TUPLE [cofactor_count: INTEGER_32]; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER_32; op1_count: INTEGER_32; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER_32; op2_count: INTEGER_32): INTEGER + require + op1_count >= op2_count + target.valid_index (target_offset) + target.valid_index (target_offset + op1_count - 1) + cofactor.valid_index (cofactor_offset) + cofactor.valid_index (cofactor_offset + op1_count - 1) + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + op1_count - 0) + op1 [op1_offset + op1_count - 1] /= 0 + op2.valid_index (op2_offset) + op2.valid_index (op2_offset + op2_count - 0) + op2 [op2_offset + op2_count - 1] /= 0 + op2_count >= 1 + local + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER_32 + s1p: SPECIAL [NATURAL_32] + s1p_offset: INTEGER + do + create tp.make_filled (0, op1_count + 1) + tp_offset := 0 + create s1p.make_filled (0, op1_count + 1) + s1p_offset := 0 + cofactor.fill_with (0, cofactor_offset, cofactor_offset + op1_count - 1) + s1p.fill_with (0, s1p_offset, s1p_offset + op1_count - 1) + cofactor [cofactor_offset] := 1 + s1p [s1p_offset] := 0 + if op1_count > op2_count then + tdiv_qr (tp, tp_offset, op1, op1_offset, op1, op1_offset, op1_count, op2, op2_offset, op2_count) + cofactor [cofactor_offset] := 0 + s1p [s1p_offset] := 1 + Result := basic_gcdext_arranged (target, target_offset, cofactor, cofactor_offset, cofactor_count, op2, op2_offset, op2_count, op1, op1_offset, op1_count, -1, s1p, s1p_offset, tp, tp_offset) + else + Result := basic_gcdext_arranged (target, target_offset, cofactor, cofactor_offset, cofactor_count, op1, op1_offset, op1_count, op2, op2_offset, op2_count, 1, s1p, s1p_offset, tp, tp_offset) + end + end + + basic_gcdext_arranged (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; cofactor_a: SPECIAL [NATURAL_32]; cofactor_offset_a: INTEGER_32; cofactor_count: TUPLE [cofactor_count: INTEGER_32]; op1_a: SPECIAL [NATURAL_32]; op1_offset_a: INTEGER_32; op1_count_a: INTEGER_32; op2_a: SPECIAL [NATURAL_32]; op2_offset_a: INTEGER_32; op2_count_a: INTEGER_32; sign_a: INTEGER; s1p_a: SPECIAL [NATURAL_32]; s1p_offset_a: INTEGER; tp_a: SPECIAL [NATURAL_32]; tp_offset_a: INTEGER): INTEGER + local + a: NATURAL_32 + b: NATURAL_32 + c: NATURAL_32 + d: NATURAL_32 + wp: SPECIAL [NATURAL_32] + wp_offset: INTEGER_32 + orig_s0p: SPECIAL [NATURAL_32] + orig_s0p_offset: INTEGER + use_double_flag: BOOLEAN + cnt: INTEGER_32 + assign_l: NATURAL_32 + op2_count: INTEGER + done: BOOLEAN + done_2: BOOLEAN + uh: NATURAL_32 + vh: NATURAL_32 + ul: NATURAL_32 + vl: NATURAL_32 + tac: NATURAL_32 + tbd: NATURAL_32 + q1: NATURAL_32 + q2: NATURAL_32 + nh: CELL [NATURAL_32] + nl: CELL [NATURAL_32] + dh: CELL [NATURAL_32] + dl: CELL [NATURAL_32] + t1: CELL [NATURAL_32] + t0: CELL [NATURAL_32] + thigh: CELL [NATURAL_32] + tlow: CELL [NATURAL_32] + sign: INTEGER + q: NATURAL_32 + t: NATURAL_32 + ssize: INTEGER_32 + qsize: INTEGER_32 + i: INTEGER_32 + cy: NATURAL_32 + cofactor: SPECIAL [NATURAL_32] + cofactor_offset: INTEGER_32 + op1: SPECIAL [NATURAL_32] + op1_offset: INTEGER_32 + op2: SPECIAL [NATURAL_32] + op2_offset: INTEGER_32 + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER_32 + s1p: SPECIAL [NATURAL_32] + s1p_offset: INTEGER_32 + temp_special: SPECIAL [NATURAL_32] + temp_integer: INTEGER_32 + op1_count: INTEGER + tsize: INTEGER + wsize: INTEGER + junk: NATURAL_32 + cy1: NATURAL_32 + cy2: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + cofactor := cofactor_a + cofactor_offset := cofactor_offset_a + op1 := op1_a + op1_offset := op1_offset_a + op1_count := op1_count_a + op2 := op2_a + op2_offset := op2_offset_a + tp := tp_a + tp_offset := tp_offset_a + s1p := s1p_a + s1p_offset := s1p_offset_a + ssize := 1 + sign := sign_a + op2_count := op2_count_a + orig_s0p := cofactor + orig_s0p_offset := cofactor_offset + create wp.make_filled (0, op1_count + 1) + wp_offset := 0 + use_double_flag := op1_count > 17 + from + until + done + loop + op2_count := op1_count + op2_count := normalize (op2, op2_offset, op2_count) + if op2_count <= 1 then + done := True + else + if use_double_flag then + uh := op1 [op1_count - 1] + vh := op2 [op1_count - 1] + ul := op1 [op1_count - 2] + vl := op2 [op1_count - 2] + cnt := leading_zeros (uh) + if cnt /= 0 then + uh := (uh |<< cnt).bit_or (ul |>> (32 - cnt)) + vh := (vh |<< cnt).bit_or (vl |>> (32 - cnt)) + vl := vl |<< cnt + ul := ul |<< cnt + if op1_count >= 3 then + ul := ul.bit_or (op1 [op1_offset + op1_count - 3] |>> (32 - cnt)) + vl := vl.bit_or (op2 [op2_offset + op1_count - 3] |>> (32 - cnt)) + end + end + a := 1 + b := 0 + c := 0 + d := 1 + assign_l := 0 + from + done_2 := False + create nh.put (0) + create nl.put (0) + create dh.put (0) + create dl.put (0) + create thigh.put (0) + create tlow.put (0) + create t1.put (0) + create t0.put (0) + until + done_2 + loop + sub_ddmmss (dh, dl, vh, vl, 0, c) + if dh.item = 0 then + done_2 := True + else + add_ssaaaa (nh, nl, uh, ul, 0, a) + q1 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item) + add_ssaaaa (dh, dl, vh, vl, 0, d) + if dh.item = 0 then + done_2 := True + else + sub_ddmmss (nh, nl, uh, ul, 0, b) + q2 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item) + if q1 /= q2 then + done_2 := True + else + tac := a + q1 * c + tbd := b + q1 * d + a := c + c := tac + b := d + d := tbd + umul_ppmm (t1, t0, q1, vl) + t1.put (t1.item + q1 * vh) + sub_ddmmss (thigh, tlow, uh, ul, t1.item, t0.item) + uh := vh + ul := vl + vh := thigh.item + vl := tlow.item + assign_l := assign_l.bit_not + add_ssaaaa (dh, dl, vh, vl, 0, c) + sub_ddmmss (nh, nl, uh, ul, 0, a) + q1 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item) + sub_ddmmss (dh, dl, vh, vl, 0, d) + if dh.item = 0 then + done_2 := True + else + add_ssaaaa (nh, nl, uh, ul, 0, b) + q2 := gcdext_div2 (nh.item, nl.item, dh.item, dl.item) + if q1 /= q2 then + done_2 := True + else + tac := a + q1 * c + tbd := b + q1 * d + a := c + c := tac + b := d + d := tbd + umul_ppmm (t1, t0, q1, vl) + t1.put (t1.item + (q1 * vh)) + sub_ddmmss (thigh, tlow, uh, ul, t1.item, t0.item) + uh := vh + ul := vl + vh := thigh.item + vl := tlow.item + assign_l := assign_l.bit_not + end + end + end + end + end + end + if assign_l /= 0 then + sign := -sign + end + else + uh := op1 [op1_offset + op1_count - 1] + vh := op2 [op2_offset + op1_count - 1] + cnt := leading_zeros (uh) + if cnt /= 0 then + uh := (uh |<< cnt).bit_or (op1 [op1_offset + op1_count - 2] |>> (limb_bits - cnt)) + vh := (vh |<< cnt).bit_or (op2 [op2_offset + op1_count - 2] |>> (limb_bits - cnt)) + end + a := 1 + b := 0 + c := 0 + d := 1 + assign_l := 0 + from + done_2 := False + until + done_2 + loop + if vh - c = 0 or vh + d = 0 then + done_2 := True + else + q := (uh + a) // (vh - c) + if q /= (uh - b) // (vh + d) then + done_2 := True + else + t := a + q * c + a := c + c := t + t := b + q * d + b := d + d := t + t := uh - q * vh + uh := vh + vh := t + assign_l := assign_l.bit_not + if vh - d = 0 then + done_2 := True + else + q := (uh - a) // (vh + c) + if q /= (uh + b) // (vh - d) then + done_2 := True + else + t := a + q * c + a := c + c := t + t := b + q * d + b := d + d := t + t := uh - q * vh + uh := vh + vh := t + assign_l := assign_l.bit_not + end + end + end + end + end + if assign_l /= 0 then + sign := -sign + end + end + if b = 0 then + tdiv_qr (wp, wp_offset, op1, op1_offset, op1, op1_offset, op1_count, op2, op2_offset, op2_count) + tp.copy_data (cofactor, cofactor_offset, tp_offset, ssize) + qsize := op1_count - op2_count + 1 + s1p.fill_with (0, s1p_offset + ssize, s1p_offset + ssize + qsize - 1) + from + i := 0 + until + i >= qsize + loop + addmul_1 (tp, tp_offset + i, s1p, s1p_offset, ssize, wp [wp_offset + i], carry) + cy := carry.item + tp [tp_offset + ssize + i] := cy + i := i + 1 + end + ssize := ssize + qsize + ssize := ssize - (tp [tp_offset + ssize - 1] = 0).to_integer + sign := -sign + temp_special := cofactor + temp_integer := cofactor_offset + cofactor := s1p + cofactor_offset := s1p_offset + s1p := temp_special + s1p_offset := temp_integer + temp_special := s1p + temp_integer := s1p_offset + s1p := tp + s1p_offset := tp_offset + tp := temp_special + tp_offset := temp_integer + op1_count := op2_count + temp_special := op1 + temp_integer := op1_offset + op1 := op2 + op1_offset := op2_offset + op2 := temp_special + op2_offset := temp_integer + else + if a = 0 then + tp.copy_data (op2, op2_offset, tp_offset, op1_count) + wp.copy_data (op1, op1_offset, wp_offset, op1_count) + submul_1 (wp, wp_offset, op2, op2_offset, op1_count, d, carry) + junk := carry.item + temp_special := tp + temp_integer := tp_offset + tp := op1 + tp_offset := op1_offset + op1 := temp_special + op1_offset := temp_integer + temp_special := wp + temp_integer := wp_offset + wp := op2 + wp_offset := op2_offset + op2 := temp_special + op2_offset := temp_integer + tp.copy_data (s1p, s1p_offset, tp_offset, ssize) + tsize := ssize + tp [tp_offset + ssize] := 0 + wp.copy_data (cofactor, cofactor_offset, wp_offset, ssize) + addmul_1 (wp, wp_offset, s1p, s1p_offset, ssize, d, carry) + cy := carry.item + wp [wp_offset + ssize] := cy + wsize := ssize + (cy /= 0).to_integer + temp_special := tp + temp_integer := tp_offset + tp := cofactor + tp_offset := cofactor_offset + cofactor := temp_special + cofactor_offset := temp_integer + temp_special := wp + temp_integer := wp_offset + wp := s1p + wp_offset := s1p_offset + s1p := temp_special + s1p_offset := temp_integer + ssize := wsize.max (tsize) + else + if assign_l /= 0 then + mul_1 (tp, tp_offset, op2, op2_offset, op1_count, b, carry) + junk := carry.item + submul_1 (tp, tp_offset, op1, op1_offset, op1_count, a, carry) + junk := carry.item + mul_1 (wp, wp_offset, op1, op1_offset, op1_count, c, carry) + junk := carry.item + submul_1 (wp, wp_offset, op2, op2_offset, op1_count, d, carry) + junk := carry.item + else + mul_1 (tp, tp_offset, op1, op1_offset, op1_count, a, carry) + junk := carry.item + submul_1 (tp, tp_offset, op2, op2_offset, op1_count, b, carry) + junk := carry.item + mul_1 (wp, wp_offset, op2, op2_offset, op1_count, d, carry) + junk := carry.item + submul_1 (wp, wp_offset, op1, op1_offset, op1_count, c, carry) + junk := carry.item + end + temp_special := tp + temp_integer := tp_offset + tp := op1 + tp_offset := op1_offset + op1 := temp_special + op1_offset := temp_integer + temp_special := wp + temp_integer := wp_offset + wp := op2 + wp_offset := op2_offset + op2 := temp_special + op2_offset := temp_integer + mul_1 (tp, tp_offset, cofactor, cofactor_offset, ssize, a, carry) + cy1 := carry.item + addmul_1 (tp, tp_offset, s1p, s1p_offset, ssize, b, carry) + cy2 := carry.item + cy := cy1 + cy2 + tp [tp_offset + ssize] := cy + tsize := ssize + (cy /= 0).to_integer + if cy < cy1 then + tp [tp_offset + tsize] := 1 + wp [wp_offset + tsize] := 0 + tsize := tsize + 1 + end + mul_1 (wp, wp_offset, s1p, s1p_offset, ssize, d, carry) + cy1 := carry.item + addmul_1 (wp, wp_offset, cofactor, cofactor_offset, ssize, c, carry) + cy2 := carry.item + cy := cy1 + cy2 + wp [wp_offset + ssize] := cy + wsize := ssize + (cy /= 0).to_integer + if cy < cy1 then + wp [wp_offset + wsize] := 1 + if wsize >= tsize then + tp [tp_offset + wsize] := 0 + end + wsize := wsize + 1 + end + temp_special := tp + temp_integer := tp_offset + tp := cofactor + tp_offset := cofactor_offset + cofactor := temp_special + cofactor_offset := temp_integer + temp_special := wp + temp_integer := wp_offset + wp := s1p + wp_offset := s1p_offset + s1p := temp_special + s1p_offset := temp_integer + ssize := wsize.max (tsize) + end + op1_count := op1_count - (op1 [op1_offset + op1_count - 1] = 0).to_integer + end + end + end + if op2_count = 0 then + if target /= op1 then + target.copy_data (op1, op1_offset, target_offset, op1_count) + end + ssize := normalize (cofactor, cofactor_offset, ssize) + if orig_s0p /= cofactor then + orig_s0p.copy_data (cofactor, cofactor_offset, orig_s0p_offset, ssize) + end + if sign >= 0 then + cofactor_count.cofactor_count := ssize + else + cofactor_count.cofactor_count := -ssize + end + Result := op1_count + else + vl := op2 [op2_offset] + t := divrem_1 (wp, wp_offset, op1, op1_offset, op1_count, vl) + tp.copy_data (cofactor, cofactor_offset, tp_offset, ssize) + qsize := op1_count - (wp [wp_offset + op1_count - 1] = 0).to_integer + if ssize < qsize then + tp.fill_with (0, tp_offset + ssize, qsize - ssize) + s1p.fill_with (0, s1p_offset + ssize, qsize) + from + i := 0 + until + i >= ssize + loop + addmul_1 (tp, tp_offset + i, wp, wp_offset, qsize, s1p [s1p_offset + i], carry) + cy := carry.item + tp [tp_offset + qsize + i] := cy + i := i + 1 + end + else + s1p.fill_with (0, s1p_offset + ssize, s1p_offset + ssize + qsize - 1) + from + i := 0 + until + i >= qsize + loop + addmul_1 (tp, tp_offset + i, s1p, s1p_offset, ssize, wp [wp_offset + i], carry) + cy := carry.item + tp [tp_offset + ssize + i] := cy + i := i + 1 + end + end + ssize := ssize + qsize + ssize := ssize - (tp [tp_offset + ssize - 1] = 0).to_integer + sign := -sign + temp_special := cofactor + temp_integer := cofactor_offset + cofactor := s1p + cofactor_offset := s1p_offset + s1p := temp_special + s1p_offset := temp_integer + temp_special := s1p + temp_integer := s1p_offset + s1p := tp + s1p_offset := tp_offset + tp := temp_special + tp_offset := temp_integer + ul := vl + vl := t + from + until + vl = 0 + loop + q := ul // vl + t := ul - q * vl + tp.copy_data (cofactor, cofactor_offset, tp_offset, ssize) + s1p.fill_with (0, s1p_offset + ssize, s1p_offset + ssize) + addmul_1 (tp, tp_offset, s1p, s1p_offset, ssize, q, carry) + cy := carry.item + tp [tp_offset + ssize] := cy + ssize := ssize + 1 + ssize := ssize - (tp [tp_offset + ssize - 1] = 0).to_integer + sign := -sign + temp_special := cofactor + temp_integer := cofactor_offset + cofactor := s1p + cofactor_offset := s1p_offset + s1p := temp_special + s1p_offset := temp_integer + temp_special := s1p + temp_integer := s1p_offset + s1p := tp + s1p_offset := tp_offset + tp := temp_special + tp_offset := temp_integer + ul := vl + vl := t + end + target [target_offset] := ul + ssize := normalize (cofactor, cofactor_offset, ssize) + if orig_s0p /= cofactor then + orig_s0p.copy_data (cofactor, cofactor_offset, orig_s0p_offset, ssize) + end + if sign >= 0 then + cofactor_count.cofactor_count := ssize + else + cofactor_count.cofactor_count := -ssize + end + Result := 1 + end + end + + gcdext (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; cofactor: SPECIAL [NATURAL_32]; cofactor_offset: INTEGER; cofactor_count: TUPLE [cofactor_count: INTEGER]; op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; op2: SPECIAL [NATURAL_32]; op2_offset: INTEGER; op2_count: INTEGER): INTEGER + require + op1_count >= op2_count + op2_count >= 0 + op1.valid_index (op1_offset) + op1.valid_index (op1_offset + op1_count - 0) + op1 [op1_offset + op1_count - 1] /= 0 + op2.valid_index (op2_offset) + op2.valid_index (op2_offset + op2_count - 0) + op1 [op1_offset + op1_count - 1] /= 0 + target.valid_index (target_offset) + target.valid_index (target_offset + op1_count - 1) + cofactor.valid_index (cofactor_offset) + cofactor.valid_index (cofactor_offset + op1_count - 1) + local + orig_n: INTEGER + do + orig_n := op2_count + Result := basic_gcdext (target, target_offset, cofactor, cofactor_offset, cofactor_count, op1, op1_offset, op1_count, op2, op2_offset, op2_count) + end + + modexact_1c_odd (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER; d: NATURAL_32; orig_c: NATURAL_32): NATURAL_32 + require + op1_count >= 1 + d.bit_test (0) + local + s: NATURAL_32 + h: CELL [NATURAL_32] + l: CELL [NATURAL_32] + inverse: NATURAL_32 + dummy: CELL [NATURAL_32] + dmul: NATURAL_32 + c: CELL [NATURAL_32] + i: INTEGER + do + create l.put (0) + create c.put (orig_c) + create h.put (0) + create dummy.put (0) + if op1_count = 1 then + s := op1 [op1_offset] + if s > c.item then + l.put (s - c.item) + h.put (l.item \\ d) + if h.item /= 0 then + h.put (d - h.item) + end + else + l.put (c.item - s) + h.put (l.item \\ d) + end + Result := h.item + else + inverse := modlimb_invert (d) + dmul := d + from + i := 0 + until + i >= op1_count - 1 + loop + s := op1 [op1_offset + i] + subc_limb (c, l, s, c.item) + l.put (l.item * inverse) + umul_ppmm (h, dummy, l.item, dmul) + c.put (c.item + h.item) + i := i + 1 + end + s := op1 [op1_offset + i] + if s <= d then + l.put (c.item - s) + if c.item < s then + l.put (l.item + d) + end + Result := l.item + else + subc_limb (c, l, s, c.item) + l.put (l.item * inverse) + umul_ppmm (h, dummy, l.item, dmul) + c.put (c.item + h.item) + Result := c.item + end + end + ensure + orig_c < d implies Result < d + orig_c >= d implies Result <= d + end + + preinv_mod_1 (up: SPECIAL [NATURAL_32]; up_offset: INTEGER; un: INTEGER; d: NATURAL_32; dinv: NATURAL_32): NATURAL_32 + require + un >= 1 + d.bit_test (31) + local + i: INTEGER + n0: NATURAL_32 + r: CELL [NATURAL_32] + dummy: CELL [NATURAL_32] + do + create r.put (up [up_offset + un - 1]) + create dummy.put (0) + if r.item >= d then + r.put (r.item - d) + end + from + i := un - 2 + until + i < 0 + loop + n0 := up [up_offset + i] + udiv_qrnnd_preinv (dummy, r, r.item, n0, d, dinv) + i := i - 1 + end + Result := r.item + end + + redc_basecase (cp: SPECIAL [NATURAL_32]; cp_offset: INTEGER; mp: SPECIAL [NATURAL_32]; mp_offset: INTEGER; n: INTEGER; n_prim: NATURAL_32; tp: SPECIAL [NATURAL_32]; tp_offset_a: INTEGER) + local + cy: NATURAL_32 + q: NATURAL_32 + j: INTEGER + tp_offset: INTEGER + junk: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + tp_offset := tp_offset_a + from + j := 0 + until + j >= n + loop + q := tp [tp_offset] * n_prim + addmul_1 (tp, tp_offset, mp, mp_offset, n, q, carry) + tp [tp_offset] := carry.item + tp_offset := tp_offset + 1 + j := j + 1 + end + add_n (cp, cp_offset, tp, tp_offset, tp, tp_offset - n, n, carry) + cy := carry.item + if cy /= 0 then + sub_n (cp, cp_offset, cp, cp_offset, mp, mp_offset, n, carry) + junk := carry.item + end + end + + subc_limb (cout: CELL [NATURAL_32]; w: CELL [NATURAL_32]; x: NATURAL_32; y: NATURAL_32) + do + w.put (x - y) + cout.put ((w.item > x).to_integer.to_natural_32) + end + + invert_gf (target: SPECIAL [NATURAL_32] target_offset: INTEGER op1_a: SPECIAL [NATURAL_32] op1_offset: INTEGER op1_count_a: INTEGER op2_a: SPECIAL [NATURAL_32] op2_offset: INTEGER op2_count_a: INTEGER) + -- Invert `op1' over `op2' using the extended euclidian algorithm in F2M + require + op2_count_a > 0 + op1_count_a >= 0 + op1_count_a <= op2_count_a; + (op1_count_a = op2_count_a) implies cmp (op1_a, op1_offset, op2_a, op2_offset, op2_count_a) <= 0 + local + op1: SPECIAL [NATURAL_32] + op1_count: INTEGER + op1_leading_zeros: INTEGER + op2: SPECIAL [NATURAL_32] + op2_count: INTEGER + op2_leading_zeros: INTEGER + tmp_special: SPECIAL [NATURAL_32] + tmp_integer: INTEGER + g1: SPECIAL [NATURAL_32] + g1_count: INTEGER + g2: SPECIAL [NATURAL_32] + g2_count: INTEGER + operand_sizes: INTEGER + left_shift_amount: INTEGER + do + operand_sizes := op2_count_a + op1_count := op1_count_a + op2_count := op2_count_a + create op1.make_filled (0, operand_sizes + operand_sizes) + create op2.make_filled (0, operand_sizes + operand_sizes) + op1.copy_data (op1_a, op1_offset, 0, op1_count.min (operand_sizes)) + op2.copy_data (op2_a, op2_offset, 0, op2_count.min (operand_sizes)) + create g1.make_filled (0, operand_sizes + operand_sizes) + create g2.make_filled (0, operand_sizes + operand_sizes) + g1 [0] := 1 + g1_count := 1 + g2_count := 0 + from + until + op1_count = 0 + loop + op1_leading_zeros := leading_zeros (op1 [op1_count - 1]) + op2_leading_zeros := leading_zeros (op2 [op2_count - 1]) + if op1_count < op2_count or (op1_count = op2_count and op1_leading_zeros > op2_leading_zeros) then + tmp_special := op1 + op1 := op2 + op2 := tmp_special + tmp_special := g1 + g1 := g2 + g2 := tmp_special + tmp_integer := op1_count + op1_count := op2_count + op2_count := tmp_integer + tmp_integer := op1_leading_zeros + op1_leading_zeros := op2_leading_zeros + op2_leading_zeros := tmp_integer + end + if op1_count /= op2_count or (op1_count = op2_count and op1_leading_zeros /= op2_leading_zeros) then + left_shift_amount := (op1_count - op2_count) * limb_bits + op2_leading_zeros - op1_leading_zeros + bit_xor_lshift (op1, 0, op1, 0, op1_count, op2, 0, op2_count, left_shift_amount) + bit_xor_lshift (g1, 0, g1, 0, operand_sizes, g2, 0, operand_sizes, left_shift_amount) + else + bit_xor (op1, 0, op1, 0, op1_count, op2, 0, op2_count) + bit_xor (g1, 0, g1, 0, operand_sizes, g2, 0, operand_sizes) + end + op1_count := normalize (op1, 0, op1_count) + op2_count := normalize (op2, 0, op2_count) + end + target.copy_data (g2, 0, target_offset, operand_sizes) + end +end diff --git a/library/crypto/eapml/facilities/special_sizing.e b/library/crypto/eapml/facilities/special_sizing.e new file mode 100644 index 00000000..d4e0a0de --- /dev/null +++ b/library/crypto/eapml/facilities/special_sizing.e @@ -0,0 +1,52 @@ +note + description: "Summary description for {NUMBER_SIZING}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Whatever you do will be insignificant, but it is very important that you do it. - Mahatma Gandhi" + +deferred class + SPECIAL_SIZING + +inherit + LIMB_MANIPULATION + MP_BASES + +feature + + sizeinbase (source: SPECIAL [NATURAL_32]; source_offset: INTEGER; size: INTEGER; base: INTEGER): INTEGER + require + size >= 0 + base >= 2 + local + lb_base: INTEGER + count: INTEGER + total_bits: INTEGER + do + if size = 0 then + Result := 1 + else + count := leading_zeros (source [source_offset + size - 1]) + total_bits := size * limb_bits - count + if pow2_p (base.to_natural_32) then + lb_base := big_base (base).to_integer_32 + Result := (total_bits + lb_base - 1) // lb_base + else + Result := ((total_bits * chars_per_bit_exactly (base)) + 1).truncated_to_integer + end + end + end + + sizeinbase_2exp (ptr: SPECIAL [NATURAL_32]; ptr_offset: INTEGER; ptr_count: INTEGER; base2exp: INTEGER): INTEGER + require + ptr_count > 0 + ptr [ptr_offset + ptr_count - 1] /= 0 + local + count: INTEGER + totbits: INTEGER + do + count := leading_zeros (ptr [ptr_offset + ptr_count - 1]) + totbits := ptr_count * limb_bits - count + Result := (totbits + base2exp - 1) // base2exp + end +end diff --git a/library/crypto/eapml/facilities/special_utility.e b/library/crypto/eapml/facilities/special_utility.e new file mode 100644 index 00000000..6d527200 --- /dev/null +++ b/library/crypto/eapml/facilities/special_utility.e @@ -0,0 +1,37 @@ +note + description: "Summary description for {NUMBER_UTILITY}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "If a law is unjust, a man is not only right to disobey it, he is obligated to do so. - Thomas Jefferson" + +deferred class + SPECIAL_UTILITY + +feature + + normalize (op1: SPECIAL [NATURAL_32]; op1_offset: INTEGER; op1_count: INTEGER): INTEGER + do + from + Result := op1_count + until + Result <= 0 or op1 [op1_offset + Result - 1] /= 0 + loop + Result := Result - 1 + end + end + + reverse (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; source: SPECIAL [NATURAL_32]; source_offset: INTEGER; count: INTEGER) + local + i: INTEGER + do + from + i := 0 + until + i >= count + loop + target [target_offset + i] := source [source_offset + count - 1 - i] + i := i + 1 + end + end +end diff --git a/library/crypto/eapml/immutable_integer_x.e b/library/crypto/eapml/immutable_integer_x.e new file mode 100644 index 00000000..cb9fd5d7 --- /dev/null +++ b/library/crypto/eapml/immutable_integer_x.e @@ -0,0 +1,66 @@ +note + description: "An INTEGER_X whos value cannot change" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Freedom is the emancipation from the arbitrary rule of other men. - Mortimer Adler (1902-2001)" + +class + IMMUTABLE_INTEGER_X + +inherit + READABLE_INTEGER_X + +create + default_create, + make_from_integer, + make_from_integer_64, + make_from_integer_32, + make_from_integer_16, + make_from_integer_8, + make_from_natural, + make_from_natural_64, + make_from_natural_32, + make_from_natural_16, + make_from_natural_8, + make_from_string, + make_from_hex_string, + make_from_string_base, + make_random, + make_from_bytes, + make_random_prime, + make_random_max, + make_limbs, + make_bits, + make_set + +convert + to_integer_64: {INTEGER_64}, + to_integer_32: {INTEGER_32}, + to_integer_16: {INTEGER_16}, + to_integer_8: {INTEGER_8}, + to_natural_64: {NATURAL_64}, + to_natural_32: {NATURAL_32}, + to_natural_16: {NATURAL_16}, + to_natural_8: {NATURAL_8}, + make_from_integer_64 ({INTEGER_64}), + make_from_integer_32 ({INTEGER_32}), + make_from_integer_16 ({INTEGER_16}), + make_from_integer_8 ({INTEGER_8}), + make_from_natural_64 ({NATURAL_64}), + make_from_natural_32 ({NATURAL_32}), + make_from_natural_16 ({NATURAL_16}), + make_from_natural_8 ({NATURAL_8}), + make_set ({READABLE_INTEGER_X}) + +feature + one: like Current + do + create Result.make_from_integer (1) + end + + zero: like Current + do + create Result + end +end diff --git a/library/crypto/eapml/integer_x.e b/library/crypto/eapml/integer_x.e new file mode 100644 index 00000000..a4860b9d --- /dev/null +++ b/library/crypto/eapml/integer_x.e @@ -0,0 +1,89 @@ +note + description: "An arbitrary precision integer" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "'For your own good' is a persuasive argument that will eventually make a man agree to his own destruction. - Janet Frame, Faces In The Water, 1982" + +class + INTEGER_X + +inherit + READABLE_INTEGER_X + export + {ANY} + abs, + plus, + minus, + product, + quotient, + opposite, + bit_complement, + bit_and, + bit_or, + bit_xor, + bit_not, + bit_xor_left_shift, + bit_shift_right, + bit_shift_left, + set_bit, + powm, + inverse, + modulo, + gcd, + invert_gf + end + +create + default_create, + make_from_integer, + make_from_integer_64, + make_from_integer_32, + make_from_integer_16, + make_from_integer_8, + make_from_natural, + make_from_natural_64, + make_from_natural_32, + make_from_natural_16, + make_from_natural_8, + make_from_string, + make_from_hex_string, + make_from_string_base, + make_random, + make_from_bytes, + make_random_prime, + make_random_max, + make_limbs, + make_bits, + make_set + +convert + to_integer_64: {INTEGER_64}, + to_integer_32: {INTEGER_32}, + to_integer_16: {INTEGER_16}, + to_integer_8: {INTEGER_8}, + to_natural_64: {NATURAL_64}, + to_natural_32: {NATURAL_32}, + to_natural_16: {NATURAL_16}, + to_natural_8: {NATURAL_8}, + make_from_integer_64 ({INTEGER_64}), + make_from_integer_32 ({INTEGER_32}), + make_from_integer_16 ({INTEGER_16}), + make_from_integer_8 ({INTEGER_8}), + make_from_natural_64 ({NATURAL_64}), + make_from_natural_32 ({NATURAL_32}), + make_from_natural_16 ({NATURAL_16}), + make_from_natural_8 ({NATURAL_8}), + make_set ({READABLE_INTEGER_X}) + +feature -- Constants + one: like Current + do + create Result.make_from_integer (1) + end + + zero: like Current + do + create Result + end +end diff --git a/library/crypto/eapml/integer_x_string_exception.e b/library/crypto/eapml/integer_x_string_exception.e new file mode 100644 index 00000000..27c4c2c1 --- /dev/null +++ b/library/crypto/eapml/integer_x_string_exception.e @@ -0,0 +1,20 @@ +note + description: "An exception when a {STRING} couldn't be parsed in to a {INTEGER_X}" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Heresy is only another word for freedom of thought. - Graham Greene (1904-1991)" + +class + INTEGER_X_STRING_EXCEPTION + +inherit + DEVELOPER_EXCEPTION + redefine + internal_meaning + end + +feature + internal_meaning: STRING = "Erorr parsing string as INTEGER_X" + +end diff --git a/library/crypto/eapml/inverse_exception.e b/library/crypto/eapml/inverse_exception.e new file mode 100644 index 00000000..956e350d --- /dev/null +++ b/library/crypto/eapml/inverse_exception.e @@ -0,0 +1,19 @@ +note + description: "An exception when an {INTEGER_X} doesn't have a modular inverse" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Whenever they burn books they will also, in the end, burn human beings. - Heinrich Heine (1797-1856), Almansor: A Tragedy, 1823" + +class + INVERSE_EXCEPTION + +inherit + DEVELOPER_EXCEPTION + redefine + internal_meaning + end + +feature + internal_meaning: STRING = "No modular inverse" +end diff --git a/library/crypto/eapml/limb_natural_32/limb_definition.e b/library/crypto/eapml/limb_natural_32/limb_definition.e new file mode 100644 index 00000000..eade1525 --- /dev/null +++ b/library/crypto/eapml/limb_natural_32/limb_definition.e @@ -0,0 +1,17 @@ +note + description: "Summary description for {LIMB_DEFINITION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + LIMB_DEFINITION + +feature + + limb_high_bit: INTEGER = 31 + -- Index of the high bit of a limb + + limb_bits: INTEGER = 32 + -- Number of bits in a limb +end diff --git a/library/crypto/eapml/limb_natural_32/limb_manipulation.e b/library/crypto/eapml/limb_natural_32/limb_manipulation.e new file mode 100644 index 00000000..d1e60af4 --- /dev/null +++ b/library/crypto/eapml/limb_natural_32/limb_manipulation.e @@ -0,0 +1,458 @@ +note + description: "Summary description for {LIMB_MANIPULATION}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + +deferred class + LIMB_MANIPULATION + +inherit + LIMB_BIT_SCANNING + LIMB_DEFINITION + +feature + + limb_low_bit: INTEGER = 0 + -- Index of the low bit of a limb + + limb_max: NATURAL_32 = 0xffffffff + -- Maximum value of limb type + + integer_to_limb (integer: INTEGER): NATURAL_32 + require + integer >= 0 + do + Result := integer.to_natural_32 + end + + boolean_to_integer (boolean: BOOLEAN): INTEGER + do + Result := boolean.to_integer + ensure + boolean implies Result = 1 + not boolean implies Result = 0 + end + + boolean_to_limb (boolean: BOOLEAN): NATURAL_32 + do + Result := boolean_to_integer (boolean).to_natural_32 + ensure + boolean implies Result = 1 + not boolean implies Result = 0 + end + + extract_limb (count: INTEGER; xh: NATURAL_32; xl: NATURAL_32): NATURAL_32 + require + count < limb_bits + count >= 0 + do + if count = 0 then + Result := xh + else + Result := (xh |<< count).bit_or (xl |>> (limb_bits - count)) + end + end + + write_limb (limb_a: NATURAL_32; target: SPECIAL [NATURAL_8]; target_offset: INTEGER) + do + target [target_offset] := limb_a.to_natural_8 + target [target_offset + 1] := (limb_a |>> 8).to_natural_8 + target [target_offset + 2] := (limb_a |>> 16).to_natural_8 + target [target_offset + 3] := (limb_a |>> 24).to_natural_8 + end + + write_limb_be (limb_a: NATURAL_32; target: SPECIAL [NATURAL_8]; target_offset: INTEGER) + do + target [target_offset] := (limb_a |>> 24).to_natural_8 + target [target_offset + 1] := (limb_a |>> 16).to_natural_8 + target [target_offset + 2] := (limb_a |>> 8).to_natural_8 + target [target_offset + 3] := limb_a.to_natural_8 + end + + read_limb (source: SPECIAL [NATURAL_8]; source_offset: INTEGER): NATURAL_32 + do + Result := source [source_offset + 3].to_natural_32 |<< 24 + Result := Result.bit_or (source [source_offset + 2].to_natural_32 |<< 16) + Result := Result.bit_or (source [source_offset + 1].to_natural_32 |<< 8) + Result := Result.bit_or (source [source_offset].to_natural_32) + end + + read_limb_be (source: SPECIAL [NATURAL_8]; source_offset: INTEGER): NATURAL_32 + do + Result := source [source_offset].to_natural_32 |<< 24 + Result := Result.bit_or (source [source_offset + 1].to_natural_32 |<< 16) + Result := Result.bit_or (source [source_offset + 2].to_natural_32 |<< 8) + Result := Result.bit_or (source [source_offset + 3].to_natural_32) + end + + udiv_qrnnd (q: TUPLE [q: NATURAL_32]; r: TUPLE [r: NATURAL_32]; n1: NATURAL_32; n0: NATURAL_32; d: NATURAL_32) + require + d /= 0 + n1 < d + local + d1: NATURAL_32 + d0: NATURAL_32 + q1: NATURAL_32 + q0: NATURAL_32 + r1: NATURAL_32 + r0: NATURAL_32 + m: NATURAL_32 + do + d1 := d.bit_shift_right (16) + d0 := d.bit_and (0xffff) + q1 := n1 // d1 + r1 := n1 - q1 * d1 + m := q1 * d0 + r1 := (r1 * 0x10000).bit_or (n0.bit_shift_right (16)) + if r1 < m then + q1 := q1 - 1 + r1 := r1 + d + if r1 >= d then + if r1 < m then + q1 := q1 - 1 + r1 := r1 + d + end + end + end + r1 := r1 - m + q0 := r1 // d1 + r0 := r1 - q0 * d1 + m := q0 * d0 + r0 := (r0 * 0x10000).bit_or (n0.bit_and (0xffff)) + if r0 < m then + q0 := q0 - 1 + r0 := r0 + d + if r0 >= d then + if r0 < m then + q0 := q0 - 1 + r0 := r0 + d + end + end + end + r0 := r0 - m + q.q := (q1 * 0x10000).bit_or (q0) + r.r := r0 + end + + limb_inverse (limb_a: NATURAL_32): NATURAL_32 + local + q: TUPLE [q: NATURAL_32] + r: TUPLE [r: NATURAL_32] + do + create q + create r + udiv_qrnnd (q, r, limb_a.bit_not, limb_max, limb_a) + Result := q.q + end + + modlimb_invert (limb_a: NATURAL_32): NATURAL_32 + require + limb_a.bit_test (0) + do + Result := modlimb_invert_table ((limb_a // 2).bit_and (0x7f).to_natural_8).to_natural_32 + Result := 2 * Result - Result * Result * limb_a + Result := 2 * Result - Result * Result * limb_a + end + + modlimb_invert_table (in: NATURAL_8): NATURAL_8 + require + in >= 0 + in <= 0x7f + do + inspect in + when 0 then + Result := 0x01 + when 1 then + Result := 0xab + when 2 then + Result := 0xcd + when 3 then + Result := 0xb7 + when 4 then + Result := 0x39 + when 5 then + Result := 0xa3 + when 6 then + Result := 0xc5 + when 7 then + Result := 0xef + when 8 then + Result := 0xf1 + when 9 then + Result := 0x1b + when 10 then + Result := 0x3d + when 11 then + Result := 0xa7 + when 12 then + Result := 0x29 + when 13 then + Result := 0x13 + when 14 then + Result := 0x35 + when 15 then + Result := 0xdf + when 16 then + Result := 0xe1 + when 17 then + Result := 0x8b + when 18 then + Result := 0xad + when 19 then + Result := 0x97 + when 20 then + Result := 0x19 + when 21 then + Result := 0x83 + when 22 then + Result := 0xa5 + when 23 then + Result := 0xcf + when 24 then + Result := 0xd1 + when 25 then + Result := 0xfb + when 26 then + Result := 0x1d + when 27 then + Result := 0x87 + when 28 then + Result := 0x09 + when 29 then + Result := 0xf4 + when 30 then + Result := 0x15 + when 31 then + Result := 0xbf + when 32 then + Result := 0xc1 + when 33 then + Result := 0x6b + when 34 then + Result := 0x8d + when 35 then + Result := 0x77 + when 36 then + Result := 0xf9 + when 37 then + Result := 0x63 + when 38 then + Result := 0x85 + when 39 then + Result := 0xaf + when 40 then + Result := 0xb1 + when 41 then + Result := 0xdb + when 42 then + Result := 0xfd + when 43 then + Result := 0x67 + when 44 then + Result := 0xe9 + when 45 then + Result := 0xd3 + when 46 then + Result := 0xf5 + when 47 then + Result := 0x9f + when 48 then + Result := 0xa1 + when 49 then + Result := 0x4b + when 50 then + Result := 0x6d + when 51 then + Result := 0x57 + when 52 then + Result := 0xd9 + when 53 then + Result := 0x43 + when 54 then + Result := 0x65 + when 55 then + Result := 0x8f + when 56 then + Result := 0x91 + when 57 then + Result := 0xbb + when 58 then + Result := 0xdd + when 59 then + Result := 0x47 + when 60 then + Result := 0xc9 + when 61 then + Result := 0xb3 + when 62 then + Result := 0xd5 + when 63 then + Result := 0x7f + when 64 then + Result := 0x81 + when 65 then + Result := 0x2b + when 66 then + Result := 0x4d + when 67 then + Result := 0x37 + when 68 then + Result := 0xb9 + when 69 then + Result := 0x23 + when 70 then + Result := 0x45 + when 71 then + Result := 0x6f + when 72 then + Result := 0x71 + when 73 then + Result := 0x9b + when 74 then + Result := 0xbd + when 75 then + Result := 0x27 + when 76 then + Result := 0xa9 + when 77 then + Result := 0x93 + when 78 then + Result := 0xb5 + when 79 then + Result := 0x5f + when 80 then + Result := 0x61 + when 81 then + Result := 0x0b + when 82 then + Result := 0x2d + when 83 then + Result := 0x17 + when 84 then + Result := 0x99 + when 85 then + Result := 0x03 + when 86 then + Result := 0x25 + when 87 then + Result := 0x4f + when 88 then + Result := 0x51 + when 89 then + Result := 0x7b + when 90 then + Result := 0x9d + when 91 then + Result := 0x07 + when 92 then + Result := 0x89 + when 93 then + Result := 0x73 + when 94 then + Result := 0x95 + when 95 then + Result := 0x3f + when 96 then + Result := 0x41 + when 97 then + Result := 0xeb + when 98 then + Result := 0x0d + when 99 then + Result := 0xf7 + when 100 then + Result := 0x79 + when 101 then + Result := 0xe3 + when 102 then + Result := 0x05 + when 103 then + Result := 0x2f + when 104 then + Result := 0x31 + when 105 then + Result := 0x5b + when 106 then + Result := 0x7d + when 107 then + Result := 0xe7 + when 108 then + Result := 0x69 + when 109 then + Result := 0x53 + when 110 then + Result := 0x75 + when 111 then + Result := 0x1f + when 112 then + Result := 0x21 + when 113 then + Result := 0xcb + when 114 then + Result := 0xed + when 115 then + Result := 0xd7 + when 116 then + Result := 0x59 + when 117 then + Result := 0xc3 + when 118 then + Result := 0xe5 + when 119 then + Result := 0x0f + when 120 then + Result := 0x11 + when 121 then + Result := 0x3b + when 122 then + Result := 0x5d + when 123 then + Result := 0xc7 + when 124 then + Result := 0x49 + when 125 then + Result := 0x33 + when 126 then + Result := 0x55 + when 127 then + Result := 0xff + end + end + + bit_index_to_limb_index (bit_a: INTEGER): INTEGER + do + Result := bit_a // limb_bits + end + + umul_ppmm (xh: CELL [NATURAL_32]; xl: CELL [NATURAL_32]; m0: NATURAL_32; m1: NATURAL_32) + local + t: NATURAL_64 + do + t := limb_multiply (m0, m1) + xl.put (t.to_natural_32) + xh.put (t.bit_shift_right (limb_bits).to_natural_32) + end + + bits_to_limbs (n: INTEGER): INTEGER + do + Result := (n + limb_bits - 1) // limb_bits + end + + bits_top_limb (n: INTEGER): INTEGER + -- How many bits of the top limb would be occupied with n bits total + do + Result := (n + limb_bits - 1) \\ limb_bits + end + + pow2_p (in: NATURAL_32): BOOLEAN + do + Result := in.bit_and (in - 1) = 0 + end + + limb_multiply (one: NATURAL_32 two: NATURAL_32): NATURAL_64 + -- Return the lossless multiplication of `one' and `two' + do + Result := one.to_natural_64 * two.to_natural_64 + end +end diff --git a/library/crypto/eapml/linear_congruential_rng.e b/library/crypto/eapml/linear_congruential_rng.e new file mode 100644 index 00000000..5055be89 --- /dev/null +++ b/library/crypto/eapml/linear_congruential_rng.e @@ -0,0 +1,249 @@ +note + description: "A Linear congruential random number generator" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "To limit the press is to insult a nation; to prohibit reading of certain books is to declare the inhabitants to be either fools or knaves. - Claude-Adrien Helvetius" + +class + LINEAR_CONGRUENTIAL_RNG + +inherit + RANDOM_NUMBER_GENERATOR + LIMB_MANIPULATION + SPECIAL_UTILITY + SPECIAL_ARITHMETIC + rename + add as add_special, + sub as sub_special, + mul as mul_special + export + {NONE} + all + end + INTEGER_X_DIVISION + +create + make + +feature + + make (size: INTEGER) + require + size >= 0 + size <= 128 + local + a: INTEGER_X + m2exp: INTEGER + number: STRING_8 + do + inspect size + when 0..16 then + m2exp := 32 + number := "29cf535" + when 17 then + m2exp := 34 + number := "A3D73AD" + when 18 then + m2exp := 36 + number := "28f825c5" + when 19 then + m2exp := 38 + number := "a3dd4cdd" + when 20 then + m2exp := 40 + number := "28f5da175" + when 21..28 then + m2exp := 56 + number := "AA7D735234C0DD" + when 29..32 then + m2exp := 64 + number := "BAECD515DAF0B49D" + when 33..50 then + m2exp := 100 + number := "292787EBD3329AD7E7575E2FD" + when 51..64 then + m2exp := 128 + number := "48A74F367FA7B5C8ACBB36901308FA85" + when 65..78 then + m2exp := 156 + number := "78A7FDDDC43611B527C3F1D760F36E5D7FC7C45" + when 79..98 then + m2exp := 196 + number := "41BA2E104EE34C66B3520CE706A56498DE6D44721E5E24F5" + when 99..100 then + m2exp := 200 + number := "4E5A24C38B981EAFE84CD9D0BEC48E83911362C114F30072C5" + when 101..238 then + m2exp := 256 + number := "AF66BA932AAF58A071FD8F0742A99A0C76982D648509973DB802303128A14CB5" + end + create a.make_from_string_base (number, 16) + randinit_lc_2exp (a, 1, m2exp) + end + +feature + + randinit_lc_2exp (a: READABLE_INTEGER_X; c: NATURAL_32; m2exp: INTEGER) + local + seedn: INTEGER + do + seedn := bits_to_limbs (m2exp) + create seed.make (m2exp, a, seedn, c) + end + + seed: RAND_LC_STRUCT + + randseed (seed_a: READABLE_INTEGER_X) + local + seedz: READABLE_INTEGER_X + seedn: INTEGER + do + seedz := seed.seed + seedn := bits_to_limbs (seed.m2exp) + fdiv_r_2exp (seedz, seed_a, seed.m2exp) + seedz.item.fill_with (0, seedz.count, seedz.count - (seedn - seedz.count)) + seedz.count := seedn + end + + randget (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; nbits: INTEGER) + local + rbitpos: INTEGER + chunk_nbits: INTEGER + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + tn: INTEGER + r2p: SPECIAL [NATURAL_32] + r2p_offset: INTEGER + rcy: NATURAL_32 + junk: INTEGER + last_nbits: INTEGER + savelimb: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + chunk_nbits := seed.m2exp // 2 + tn := bits_to_limbs (chunk_nbits) + create tp.make_filled (0, tn) + from + rbitpos := 0 + until + rbitpos + chunk_nbits > nbits + loop + r2p := target + r2p_offset := target_offset + rbitpos // limb_bits + if rbitpos \\ limb_bits /= 0 then + junk := lc (tp, tp_offset) + savelimb := r2p [r2p_offset] + lshift (r2p, r2p_offset, tp, tp_offset, tn, rbitpos \\ limb_bits, carry) + rcy := carry.item + r2p [r2p_offset] := r2p [r2p_offset].bit_or (savelimb) + if (chunk_nbits \\ limb_bits + rbitpos \\ limb_bits) > limb_bits then + r2p [r2p_offset + tn] := rcy + end + else + junk := lc (r2p, r2p_offset) + end + rbitpos := rbitpos + chunk_nbits + end + if rbitpos /= nbits then + r2p := target + r2p_offset := target_offset + rbitpos // limb_bits + last_nbits := nbits - rbitpos + tn := bits_to_limbs (last_nbits) + junk := lc (tp, tp_offset) + if rbitpos \\ limb_bits /= 0 then + savelimb := r2p [r2p_offset] + lshift (r2p, r2p_offset, tp, tp_offset, tn, rbitpos \\ limb_bits, carry) + rcy := carry.item + r2p [r2p_offset] := r2p [r2p_offset].bit_or (savelimb) + if rbitpos + tn * limb_bits - rbitpos \\ limb_bits < nbits then + r2p [r2p_offset + tn] := rcy + end + else + r2p.copy_data (tp, tp_offset, r2p_offset, tn) + end + if nbits \\ limb_bits /= 0 then + target [target_offset + nbits // limb_bits] := target [target_offset + nbits // limb_bits].bit_and (((0).to_natural_32.bit_not |<< (nbits \\ limb_bits)).bit_not) + end + end + end + + lc (target: SPECIAL [NATURAL_32]; target_offset: INTEGER): INTEGER + local + tp: SPECIAL [NATURAL_32] + tp_offset: INTEGER + seedp: SPECIAL [NATURAL_32] + seedp_offset: INTEGER + ap: SPECIAL [NATURAL_32] + ap_offset: INTEGER + ta: INTEGER + tn: INTEGER + seedn: INTEGER + an: INTEGER + m2exp: INTEGER + bits: INTEGER + cy: INTEGER + xn: INTEGER + tmp: INTEGER + i: INTEGER + x: NATURAL_32 + limb: NATURAL_32 + count: INTEGER + junk: NATURAL_32 + carry: CELL [NATURAL_32] + do + create carry.put (0) + m2exp := seed.m2exp + seedp := seed.seed.item + seedn := seed.seed.count + ap := seed.a.item + an := seed.a.count + ta := an + seedn + 1 + tn := bits_to_limbs (m2exp) + if ta <= tn then + tmp := an + seedn + ta := tn + 1 + end + create tp.make_filled (0, ta) + mul_special (tp, tp_offset, seedp, seedp_offset, seedn, ap, ap_offset, an, carry) + junk := carry.item + i := seed.cn + if i /= 0 then + add_n (tp, tp_offset, tp, tp_offset, seed.cp, 0, i, carry) + if carry.item /= 0 then + from + cy := 0 + limb := 1 + until + cy /= 0 or limb = 0 + loop + if i >= tn then + cy := 1 + else + x := tp [tp_offset + i] + limb := x + 1 + tp [tp_offset + i] := limb + i := i + 1 + end + end + end + end + tp [tp_offset + m2exp // limb_bits] := tp [tp_offset + m2exp // limb_bits].bit_and ((integer_to_limb (1) |<< m2exp \\ integer_to_limb (limb_bits)) - 1) + seed.seed.item.copy_data (tp, tp_offset, 0, tn) + bits := m2exp // 2 + xn := bits // limb_bits + tn := tn - xn + if tn > 0 then + count := bits \\ limb_bits + if count /= 0 then + rshift (tp, tp_offset, tp, tp_offset + xn, tn, count, carry) + junk := carry.item + target.copy_data (tp, tp_offset, target_offset, xn + 1) + else + target.copy_data (tp, tp_offset + xn, target_offset, tn) + end + end + Result := (m2exp + 1) // 2 + end +end diff --git a/library/crypto/eapml/mersenne_twister_rng.e b/library/crypto/eapml/mersenne_twister_rng.e new file mode 100644 index 00000000..63ea1e40 --- /dev/null +++ b/library/crypto/eapml/mersenne_twister_rng.e @@ -0,0 +1,1490 @@ +note + description: "A Mersenne twister RNG" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "A censor is a man who knows more than he thinks you ought to. - Granville Hicks (1901-1982)" + +class + MERSENNE_TWISTER_RNG + +inherit + RANDOM_NUMBER_GENERATOR + INTEGER_X_ARITHMETIC + rename + cmp as cmp_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_DIVISION + rename + cmp as cmp_special, + mod as mod_integer_x, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + end + INTEGER_X_COMPARISON + INTEGER_X_LOGIC + rename + add as add_special, + sub as sub_special, + mul as mul_special + end + +create + make + +feature + make + do + create mt.make_filled (0, n) + randinit_mt_noseed + end + +feature + + randinit_mt_noseed + local + i: INTEGER + do + from + i := 0 + until + i >= n + loop + mt [i] := default_state (i) + i := i + 1 + end + mti := warm_up \\ n + end + + mangle_seed (r: READABLE_INTEGER_X; b_orig: READABLE_INTEGER_X) + local + t: INTEGER_X + b: INTEGER_X + e: NATURAL_32 + bit_l: NATURAL_32 + sign: INTEGER + reduce: BOOLEAN + do + e := 0x40118124 + bit_l := 0x20000000 + create t + create b.make_set (b_orig) + r.copy (b) + from + until + bit_l = 0 + loop + from + reduce := True + until + not reduce + loop + from + sign := 1 + until + sign = 0 + loop + tdiv_q_2exp (t, r, 0x19937) + sign := t.sign + if sign /= 0 then + tdiv_r_2exp (r, r, 0x19937) + addmul_ui (r, r, 0x20023) + end + end + if e.bit_and (bit_l) /= 0 then + e := e.bit_and (bit_l.bit_not) + mul (r, r, b) + else + reduce := False + end + end + bit_l := bit_l |>> 1 + end + end + + randseed (seed: READABLE_INTEGER_X) + local + i: INTEGER + count: INTEGER + mod: INTEGER_X + seed1: INTEGER_X + do + create mod.make_from_natural (0) + create seed1 + bit_set (mod, 19937) + sub_ui (mod, mod, 20027) + mod_integer_x (seed1, seed, mod) + add_ui (seed1, seed1, 2) + mangle_seed (seed1, seed1) + if bit_test (seed1, 19936) then + mt [0] := 0x80000000 + else + mt [0] := 0x0 + end + bit_clear (seed1, 19936) + mt.copy_data (seed1.item, 0, 1, seed1.count) + count := count + 1 + from + until + count >= n + loop + mt [count] := 0 + count := count + 1 + end + if warm_up /= 0 then + from + i := 0 + until + i >= warm_up // n + loop + recalc_buffer + i := i + 1 + end + end + mti := warm_up \\ n + end + + recalc_buffer + local + y: NATURAL_32 + kk: INTEGER + do + from + kk := 0 + until + kk >= n - m + loop + y := mt [kk].bit_and (0x80000000).bit_or (mt [kk + 1].bit_and (0x7fffffff)) + if y.bit_test (0) then + mt [kk] := mt [kk + m].bit_xor (y |>> 1).bit_xor (matrix_a) + else + mt [kk] := mt [kk + m].bit_xor (y |>> 1) + end + kk := kk + 1 + end + from + until + kk >= n - 1 + loop + y := mt [kk].bit_and (0x80000000).bit_or (mt [kk + 1].bit_and (0x7fffffff)) + if y.bit_test (0) then + mt [kk] := mt [kk - (n - m)].bit_xor (y |>> 1).bit_xor (matrix_a) + else + mt [kk] := mt [kk - (n - m)].bit_xor (y |>> 1) + end + kk := kk + 1 + end + y := mt [n - 1].bit_and (0x80000000).bit_or (mt [0].bit_and (0x7fffffff)) + if y.bit_test (0) then + mt [n - 1] := mt [m - 1].bit_xor (y |>> 1).bit_xor (matrix_a) + else + mt [n - 1] := mt [m - 1].bit_xor (y |>> 1) + end + end + + next_random (y: CELL [NATURAL_32]) + do + if mti >= n then + recalc_buffer + mti := 0 + end + y.put (mt [mti]) + mti := mti + 1 + y.put (y.item.bit_xor (y.item |>> 11)) + y.put (y.item.bit_xor ((y.item |<< 7).bit_and (mask_1))) + y.put (y.item.bit_xor ((y.item |<< 15).bit_and (mask_2))) + y.put (y.item.bit_xor (y.item |>> 18)) + end + + randget (target: SPECIAL [NATURAL_32]; target_offset: INTEGER_32; count: INTEGER_32) + local + y: CELL [NATURAL_32] + rbits: INTEGER + i: INTEGER + nlimbs: INTEGER + do + create y.put (0) + nlimbs := count // 32 + rbits := count \\ 32 + from + i := 0 + until + i >= nlimbs + loop + next_random (y) + target [target_offset + i] := y.item + i := i + 1 + end + if rbits /= 0 then + next_random (y) + target [target_offset + nlimbs] := y.item.bit_and (((0xffffffff).to_natural_32 |<< rbits).bit_not) + end + end + + mti: INTEGER + mt: SPECIAL [NATURAL_32] + n: INTEGER = 624 + m: INTEGER = 397 + matrix_a: NATURAL_32 = 0x9908b0df + warm_up: INTEGER = 2000 + default_seed: INTEGER = 5489 + mask_1: NATURAL_32 = 0x9d2c5680 + mask_2: NATURAL_32 = 0xefc60000 + + default_state (i: INTEGER): NATURAL_32 + do + inspect + i + when 0 then + Result := 0xD247B233 + when 1 then + Result := 0x9E5AA8F1 + when 2 then + Result := 0x0FFA981B + when 3 then + Result := 0x9DCB0980 + when 4 then + Result := 0x74200F2B + when 5 then + Result := 0xA576D044 + when 6 then + Result := 0xE9F05ADF + when 7 then + Result := 0x1538BFF5 + when 8 then + Result := 0x59818BBF + when 9 then + Result := 0xCF9E58D8 + when 10 then + Result := 0x09FCE032 + when 11 then + Result := 0x6A1C663F + when 12 then + Result := 0x5116E78A + when 13 then + Result := 0x69B3E0FA + when 14 then + Result := 0x6D92D665 + when 15 then + Result := 0xD0A8BE98 + when 16 then + Result := 0xF669B734 + when 17 then + Result := 0x41AC1B68 + when 18 then + Result := 0x630423F1 + when 19 then + Result := 0x4B8D6B8A + when 20 then + Result := 0xC2C46DD7 + when 21 then + Result := 0x5680747D + when 22 then + Result := 0x43703E8F + when 23 then + Result := 0x3B6103D2 + when 24 then + Result := 0x49E5EB3F + when 25 then + Result := 0xCBDAB4C1 + when 26 then + Result := 0x9C988E23 + when 27 then + Result := 0x747BEE0B + when 28 then + Result := 0x9111E329 + when 29 then + Result := 0x9F031B5A + when 30 then + Result := 0xECCA71B9 + when 31 then + Result := 0x2AFE4EF8 + when 32 then + Result := 0x8421C7ED + when 33 then + Result := 0xAC89AFF1 + when 34 then + Result := 0xAED90DF3 + when 35 then + Result := 0x2DD74F01 + when 36 then + Result := 0x14906A13 + when 37 then + Result := 0x75873FA9 + when 38 then + Result := 0xFF83F877 + when 39 then + Result := 0x5028A0C9 + when 40 then + Result := 0x11B4C41D + when 41 then + Result := 0x7CAEDBC4 + when 42 then + Result := 0x8672D0A7 + when 43 then + Result := 0x48A7C109 + when 44 then + Result := 0x8320E59F + when 45 then + Result := 0xBC0B3D5F + when 46 then + Result := 0x75A30886 + when 47 then + Result := 0xF9E0D128 + when 48 then + Result := 0x41AF7580 + when 49 then + Result := 0x239BB94D + when 50 then + Result := 0xC67A3C81 + when 51 then + Result := 0x74EEBD6E + when 52 then + Result := 0xBC02B53C + when 53 then + Result := 0x727EA449 + when 54 then + Result := 0x6B8A2806 + when 55 then + Result := 0x5853B0DA + when 56 then + Result := 0xBDE032F4 + when 57 then + Result := 0xCE234885 + when 58 then + Result := 0x320D6145 + when 59 then + Result := 0x48CC053F + when 60 then + Result := 0x00DBC4D2 + when 61 then + Result := 0xD55A2397 + when 62 then + Result := 0xE1059B6F + when 63 then + Result := 0x1C3E05D1 + when 64 then + Result := 0x09657C64 + when 65 then + Result := 0xD07CB661 + when 66 then + Result := 0x6E982E34 + when 67 then + Result := 0x6DD1D777 + when 68 then + Result := 0xEDED1071 + when 69 then + Result := 0xD79DFD65 + when 70 then + Result := 0xF816DDCE + when 71 then + Result := 0xB6FAF1E4 + when 72 then + Result := 0x1C771074 + when 73 then + Result := 0x311835BD + when 74 then + Result := 0x18F952F7 + when 75 then + Result := 0xF8F40350 + when 76 then + Result := 0x4ECED354 + when 77 then + Result := 0x7C8AC12B + when 78 then + Result := 0x31A9994D + when 79 then + Result := 0x4FD47747 + when 80 then + Result := 0xDC227A23 + when 81 then + Result := 0x6DFAFDDF + when 82 then + Result := 0x6796E748 + when 83 then + Result := 0x0C6F634F + when 84 then + Result := 0xF992FA1D + when 85 then + Result := 0x4CF670C9 + when 86 then + Result := 0x067DFD31 + when 87 then + Result := 0xA7A3E1A5 + when 88 then + Result := 0x8CD7D9DF + when 89 then + Result := 0x972CCB34 + when 90 then + Result := 0x67C82156 + when 91 then + Result := 0xD548F6A8 + when 92 then + Result := 0x045CEC21 + when 93 then + Result := 0xF3240BFB + when 94 then + Result := 0xDEF656A7 + when 95 then + Result := 0x43DE08C5 + when 96 then + Result := 0xDAD1F92F + when 97 then + Result := 0x3726C56B + when 98 then + Result := 0x1409F19A + when 99 then + Result := 0x942FD147 + when 100 then + Result := 0xB926749C + when 101 then + Result := 0xADDC31B8 + when 102 then + Result := 0x53D0D869 + when 103 then + Result := 0xD1BA52FE + when 104 then + Result := 0x6722DF8C + when 105 then + Result := 0x22D95A74 + when 106 then + Result := 0x7DC1B52A + when 107 then + Result := 0x1DEC6FD5 + when 108 then + Result := 0x7262874D + when 109 then + Result := 0x0A725DC9 + when 110 then + Result := 0xE6A8193D + when 111 then + Result := 0xA052835A + when 112 then + Result := 0xDC9AD928 + when 113 then + Result := 0xE59EBB90 + when 114 then + Result := 0x70DBA9FF + when 115 then + Result := 0xD612749D + when 116 then + Result := 0x5A5A638C + when 117 then + Result := 0x6086EC37 + when 118 then + Result := 0x2A579709 + when 119 then + Result := 0x1449EA3A + when 120 then + Result := 0xBC8E3C06 + when 121 then + Result := 0x2F900666 + when 122 then + Result := 0xFBE74FD1 + when 123 then + Result := 0x6B35B911 + when 124 then + Result := 0xF8335008 + when 125 then + Result := 0xEF1E979D + when 126 then + Result := 0x738AB29D + when 127 then + Result := 0xA2DC0FDC + when 128 then + Result := 0x7696305D + when 129 then + Result := 0xF5429DAC + when 130 then + Result := 0x8C41813B + when 131 then + Result := 0x8073E02E + when 132 then + Result := 0xBEF83CCD + when 133 then + Result := 0x7B50A95A + when 134 then + Result := 0x05EE5862 + when 135 then + Result := 0x00829ECE + when 136 then + Result := 0x8CA1958C + when 137 then + Result := 0xBE4EA2E2 + when 138 then + Result := 0x4293BB73 + when 139 then + Result := 0x656F7B23 + when 140 then + Result := 0x417316D8 + when 141 then + Result := 0x4467D7CF + when 142 then + Result := 0x2200E63B + when 143 then + Result := 0x109050C8 + when 144 then + Result := 0x814CBE47 + when 145 then + Result := 0x36B1D4A8 + when 146 then + Result := 0x36AF9305 + when 147 then + Result := 0x308327B3 + when 148 then + Result := 0xEBCD7344 + when 149 then + Result := 0xA738DE27 + when 150 then + Result := 0x5A10C399 + when 151 then + Result := 0x4142371D + when 152 then + Result := 0x64A18528 + when 153 then + Result := 0x0B31E8B2 + when 154 then + Result := 0x641057B9 + when 155 then + Result := 0x6AFC363B + when 156 then + Result := 0x108AD953 + when 157 then + Result := 0x9D4DA234 + when 158 then + Result := 0x0C2D9159 + when 159 then + Result := 0x1C8A1A1F + when 160 then + Result := 0x310C66BA + when 161 then + Result := 0x87AA1070 + when 162 then + Result := 0xDAC832FF + when 163 then + Result := 0x0A433422 + when 164 then + Result := 0x7AF15812 + when 165 then + Result := 0x2D8D9BD0 + when 166 then + Result := 0x995A25E9 + when 167 then + Result := 0x25326CAC + when 168 then + Result := 0xA34384DB + when 169 then + Result := 0x4C8421CC + when 170 then + Result := 0x4F0315EC + when 171 then + Result := 0x29E8649E + when 172 then + Result := 0xA7732D6F + when 173 then + Result := 0x2E94D3E3 + when 174 then + Result := 0x7D98A340 + when 175 then + Result := 0x397C4D74 + when 176 then + Result := 0x659DB4DE + when 177 then + Result := 0x747D4E9A + when 178 then + Result := 0xD9DB8435 + when 179 then + Result := 0x4659DBE9 + when 180 then + Result := 0x313E6DC5 + when 181 then + Result := 0x29D104DC + when 182 then + Result := 0x9F226CBA + when 183 then + Result := 0x452F18B0 + when 184 then + Result := 0xD0BC5068 + when 185 then + Result := 0x844CA299 + when 186 then + Result := 0x782B294E + when 187 then + Result := 0x4AE2EB7B + when 188 then + Result := 0xA4C475F8 + when 189 then + Result := 0x70A81311 + when 190 then + Result := 0x4B3E8BCC + when 191 then + Result := 0x7E20D4BA + when 192 then + Result := 0xABCA33C9 + when 193 then + Result := 0x57BE2960 + when 194 then + Result := 0x44F9B419 + when 195 then + Result := 0x2E567746 + when 196 then + Result := 0x72EB757A + when 197 then + Result := 0x102CC0E8 + when 198 then + Result := 0xB07F32B9 + when 199 then + Result := 0xD0DABD59 + when 200 then + Result := 0xBA85AD6B + when 201 then + Result := 0xF3E20667 + when 202 then + Result := 0x98D77D81 + when 203 then + Result := 0x197AFA47 + when 204 then + Result := 0x518EE9AC + when 205 then + Result := 0xE10CE5A2 + when 206 then + Result := 0x01CF2C2A + when 207 then + Result := 0xD3A3AF3D + when 208 then + Result := 0x16DDFD65 + when 209 then + Result := 0x669232F8 + when 210 then + Result := 0x1C50A301 + when 211 then + Result := 0xB93D9151 + when 212 then + Result := 0x9354D3F4 + when 213 then + Result := 0x847D79D0 + when 214 then + Result := 0xD5FE2EC6 + when 215 then + Result := 0x1F7B0610 + when 216 then + Result := 0xFA6B90A5 + when 217 then + Result := 0xC5879041 + when 218 then + Result := 0x2E7DC05E + when 219 then + Result := 0x423F1F32 + when 220 then + Result := 0xEF623DDB + when 221 then + Result := 0x49C13280 + when 222 then + Result := 0x98714E92 + when 223 then + Result := 0xC7B6E4AD + when 224 then + Result := 0xC4318466 + when 225 then + Result := 0x0737F312 + when 226 then + Result := 0x4D3C003F + when 227 then + Result := 0x9ACC1F1F + when 228 then + Result := 0x5F1C926D + when 229 then + Result := 0x085FA771 + when 230 then + Result := 0x185A83A2 + when 231 then + Result := 0xF9AA159D + when 232 then + Result := 0x0B0B0132 + when 233 then + Result := 0xF98E7A43 + when 234 then + Result := 0xCD9EBDBE + when 235 then + Result := 0x0190CB29 + when 236 then + Result := 0x10D93FB6 + when 237 then + Result := 0x3B8A4D97 + when 238 then + Result := 0x66A65A41 + when 239 then + Result := 0xE43E766F + when 240 then + Result := 0x77BE3C41 + when 241 then + Result := 0xB9686364 + when 242 then + Result := 0xCB36994D + when 243 then + Result := 0x6846A287 + when 244 then + Result := 0x567E77F7 + when 245 then + Result := 0x36178DD8 + when 246 then + Result := 0xBDE6B1F2 + when 247 then + Result := 0xB6EFDC64 + when 248 then + Result := 0x82950324 + when 249 then + Result := 0x42053F47 + when 250 then + Result := 0xC09BE51C + when 251 then + Result := 0x0942D762 + when 252 then + Result := 0x35F92C7F + when 253 then + Result := 0x367DEC61 + when 254 then + Result := 0x6EE3D983 + when 255 then + Result := 0xDBAAF78A + when 256 then + Result := 0x265D2C47 + when 257 then + Result := 0x8EB4BF5C + when 258 then + Result := 0x33B232D7 + when 259 then + Result := 0xB0137E77 + when 260 then + Result := 0x373C39A7 + when 261 then + Result := 0x8D2B2E76 + when 262 then + Result := 0xC7510F01 + when 263 then + Result := 0x50F9E032 + when 264 then + Result := 0x7B1FDDDB + when 265 then + Result := 0x724C2AAE + when 266 then + Result := 0xB10ECB31 + when 267 then + Result := 0xCCA3D1B8 + when 268 then + Result := 0x7F0BCF10 + when 269 then + Result := 0x4254BBBD + when 270 then + Result := 0xE3F93B97 + when 271 then + Result := 0x2305039B + when 272 then + Result := 0x53120E22 + when 273 then + Result := 0x1A2F3B9A + when 274 then + Result := 0x0FDDBD97 + when 275 then + Result := 0x0118561E + when 276 then + Result := 0x0A798E13 + when 277 then + Result := 0x9E0B3ACD + when 278 then + Result := 0xDB6C9F15 + when 279 then + Result := 0xF512D0A2 + when 280 then + Result := 0x9E8C3A28 + when 281 then + Result := 0xEE2184AE + when 282 then + Result := 0x0051EC2F + when 283 then + Result := 0x2432F74F + when 284 then + Result := 0xB0AA66EA + when 285 then + Result := 0x55128D88 + when 286 then + Result := 0xF7D83A38 + when 287 then + Result := 0x4DAE8E82 + when 288 then + Result := 0x3FDC98D6 + when 289 then + Result := 0x5F0BD341 + when 290 then + Result := 0x7244BE1D + when 291 then + Result := 0xC7B48E78 + when 292 then + Result := 0x2D473053 + when 293 then + Result := 0x43892E20 + when 294 then + Result := 0xBA0F1F2A + when 295 then + Result := 0x524D4895 + when 296 then + Result := 0x2E10BCB1 + when 297 then + Result := 0x4C372D81 + when 298 then + Result := 0x5C3E50CD + when 299 then + Result := 0xCF61CC2E + when 300 then + Result := 0x931709AB + when 301 then + Result := 0x81B3AEFC + when 302 then + Result := 0x39E9405E + when 303 then + Result := 0x7FFE108C + when 304 then + Result := 0x4FBB3FF8 + when 305 then + Result := 0x06ABE450 + when 306 then + Result := 0x7F5BF51E + when 307 then + Result := 0xA4E3CDFD + when 308 then + Result := 0xDB0F6C6F + when 309 then + Result := 0x159A1227 + when 310 then + Result := 0x3B9FED55 + when 311 then + Result := 0xD20B6F7F + when 312 then + Result := 0xFBE9CC83 + when 313 then + Result := 0x64856619 + when 314 then + Result := 0xBF52B8AF + when 315 then + Result := 0x9D7006B0 + when 316 then + Result := 0x71165BC6 + when 317 then + Result := 0xAE324AEE + when 318 then + Result := 0x29D27F2C + when 319 then + Result := 0x794C2086 + when 320 then + Result := 0x74445CE2 + when 321 then + Result := 0x782915CC + when 322 then + Result := 0xD4CE6886 + when 323 then + Result := 0x3289AE7C + when 324 then + Result := 0x53DEF297 + when 325 then + Result := 0x4185F7ED + when 326 then + Result := 0x88B72400 + when 327 then + Result := 0x3C09DC11 + when 328 then + Result := 0xBCE3AAB6 + when 329 then + Result := 0x6A75934A + when 330 then + Result := 0xB267E399 + when 331 then + Result := 0x000DF1BF + when 332 then + Result := 0x193BA5E2 + when 333 then + Result := 0xFA3E1977 + when 334 then + Result := 0x179E14F6 + when 335 then + Result := 0x1EEDE298 + when 336 then + Result := 0x691F0B06 + when 337 then + Result := 0xB84F78AC + when 338 then + Result := 0xC1C15316 + when 339 then + Result := 0xFFFF3AD6 + when 340 then + Result := 0x0B457383 + when 341 then + Result := 0x518CD612 + when 342 then + Result := 0x05A00F3E + when 343 then + Result := 0xD5B7D275 + when 344 then + Result := 0x4C5ECCD7 + when 345 then + Result := 0xE02CD0BE + when 346 then + Result := 0x5558E9F2 + when 347 then + Result := 0x0C89BBF0 + when 348 then + Result := 0xA3D96227 + when 349 then + Result := 0x2832D2B2 + when 350 then + Result := 0xF667B897 + when 351 then + Result := 0xD4556554 + when 352 then + Result := 0xF9D2F01F + when 353 then + Result := 0xFA1E3FAE + when 354 then + Result := 0x52C2E1EE + when 355 then + Result := 0xE5451F31 + when 356 then + Result := 0x7E849729 + when 357 then + Result := 0xDABDB67A + when 358 then + Result := 0x54BF5E7E + when 359 then + Result := 0xF831C271 + when 360 then + Result := 0x5F1A17E3 + when 361 then + Result := 0x9D140AFE + when 362 then + Result := 0x92741C47 + when 363 then + Result := 0x48CFABCE + when 364 then + Result := 0x9CBBE477 + when 365 then + Result := 0x9C3EE57F + when 366 then + Result := 0xB07D4C39 + when 367 then + Result := 0xCC21BCE2 + when 368 then + Result := 0x697708B1 + when 369 then + Result := 0x58DA2A6B + when 370 then + Result := 0x2370DB16 + when 371 then + Result := 0x6E641948 + when 372 then + Result := 0xACC5BD52 + when 373 then + Result := 0x868F24CC + when 374 then + Result := 0xCA1DB0F5 + when 375 then + Result := 0x4CADA492 + when 376 then + Result := 0x3F443E54 + when 377 then + Result := 0xC4A4D5E9 + when 378 then + Result := 0xF00AD670 + when 379 then + Result := 0xE93C86E0 + when 380 then + Result := 0xFE90651A + when 381 then + Result := 0xDDE532A3 + when 382 then + Result := 0xA66458DF + when 383 then + Result := 0xAB7D7151 + when 384 then + Result := 0x0E2E775F + when 385 then + Result := 0xC9109F99 + when 386 then + Result := 0x8D96D59F + when 387 then + Result := 0x73CEF14C + when 388 then + Result := 0xC74E88E9 + when 389 then + Result := 0x02712DC0 + when 390 then + Result := 0x04F41735 + when 391 then + Result := 0x2E5914A2 + when 392 then + Result := 0x59F4B2FB + when 393 then + Result := 0x0287FC83 + when 394 then + Result := 0x80BC0343 + when 395 then + Result := 0xF6B32559 + when 396 then + Result := 0xC74178D4 + when 397 then + Result := 0xF1D99123 + when 398 then + Result := 0x383CCC07 + when 399 then + Result := 0xACC0637D + when 400 then + Result := 0x0863A548 + when 401 then + Result := 0xA6FCAC85 + when 402 then + Result := 0x2A13EFF0 + when 403 then + Result := 0xAF2EEDB1 + when 404 then + Result := 0x41E72750 + when 405 then + Result := 0xE0C6B342 + when 406 then + Result := 0x5DA22B46 + when 407 then + Result := 0x635559E0 + when 408 then + Result := 0xD2EA40AC + when 409 then + Result := 0x10AA98C0 + when 410 then + Result := 0x19096497 + when 411 then + Result := 0x112C542B + when 412 then + Result := 0x2C85040C + when 413 then + Result := 0xA868E7D0 + when 414 then + Result := 0x6E260188 + when 415 then + Result := 0xF596D390 + when 416 then + Result := 0xC3BB5D7A + when 417 then + Result := 0x7A2AA937 + when 418 then + Result := 0xDFD15032 + when 419 then + Result := 0x6780AE3B + when 420 then + Result := 0xDB5F9CD8 + when 421 then + Result := 0x8BD266B0 + when 422 then + Result := 0x7744AF12 + when 423 then + Result := 0xB463B1B0 + when 424 then + Result := 0x589629C9 + when 425 then + Result := 0xE30DBC6E + when 426 then + Result := 0x880F5569 + when 427 then + Result := 0x209E6E16 + when 428 then + Result := 0x9DECA50C + when 429 then + Result := 0x02987A57 + when 430 then + Result := 0xBED3EA57 + when 431 then + Result := 0xD3A678AA + when 432 then + Result := 0x70DD030D + when 433 then + Result := 0x0CFD9C5D + when 434 then + Result := 0x92A18E99 + when 435 then + Result := 0xF5740619 + when 436 then + Result := 0x7F6F0A7D + when 437 then + Result := 0x134CAF9A + when 438 then + Result := 0x70F5BAE4 + when 439 then + Result := 0x23DCA7B5 + when 440 then + Result := 0x4D788FCD + when 441 then + Result := 0xC7F07847 + when 442 then + Result := 0xBCF77DA1 + when 443 then + Result := 0x9071D568 + when 444 then + Result := 0xFC627EA1 + when 445 then + Result := 0xAE004B77 + when 446 then + Result := 0x66B54BCB + when 447 then + Result := 0x7EF2DAAC + when 448 then + Result := 0xDCD5AC30 + when 449 then + Result := 0xB9BDF730 + when 450 then + Result := 0x505A97A7 + when 451 then + Result := 0x9D881FD3 + when 452 then + Result := 0xADB796CC + when 453 then + Result := 0x94A1D202 + when 454 then + Result := 0x97535D7F + when 455 then + Result := 0x31EC20C0 + when 456 then + Result := 0xB1887A98 + when 457 then + Result := 0xC1475069 + when 458 then + Result := 0xA6F73AF3 + when 459 then + Result := 0x71E4E067 + when 460 then + Result := 0x46A569DE + when 461 then + Result := 0xD2ADE430 + when 462 then + Result := 0x6F0762C7 + when 463 then + Result := 0xF50876F4 + when 464 then + Result := 0x53510542 + when 465 then + Result := 0x03741C3E + when 466 then + Result := 0x53502224 + when 467 then + Result := 0xD8E54D60 + when 468 then + Result := 0x3C44AB1A + when 469 then + Result := 0x34972B46 + when 470 then + Result := 0x74BFA89D + when 471 then + Result := 0xD7D768E0 + when 472 then + Result := 0x37E605DC + when 473 then + Result := 0xE13D1BDF + when 474 then + Result := 0x5051C421 + when 475 then + Result := 0xB9E057BE + when 476 then + Result := 0xB717A14C + when 477 then + Result := 0xA1730C43 + when 478 then + Result := 0xB99638BE + when 479 then + Result := 0xB5D5F36D + when 480 then + Result := 0xE960D9EA + when 481 then + Result := 0x6B1388D3 + when 482 then + Result := 0xECB6D3B6 + when 483 then + Result := 0xBDBE8B83 + when 484 then + Result := 0x2E29AFC5 + when 485 then + Result := 0x764D71EC + when 486 then + Result := 0x4B8F4F43 + when 487 then + Result := 0xC21DDC00 + when 488 then + Result := 0xA63F657F + when 489 then + Result := 0x82678130 + when 490 then + Result := 0xDBF535AC + when 491 then + Result := 0xA594FC58 + when 492 then + Result := 0x942686BC + when 493 then + Result := 0xBD9B657B + when 494 then + Result := 0x4A0F9B61 + when 495 then + Result := 0x44FF184F + when 496 then + Result := 0x38E10A2F + when 497 then + Result := 0x61910626 + when 498 then + Result := 0x5E247636 + when 499 then + Result := 0x7106D137 + when 500 then + Result := 0xC62802F0 + when 501 then + Result := 0xBD1D1F00 + when 502 then + Result := 0x7CC0DCB2 + when 503 then + Result := 0xED634909 + when 504 then + Result := 0xDC13B24E + when 505 then + Result := 0x9799C499 + when 506 then + Result := 0xD77E3D6A + when 507 then + Result := 0x14773B68 + when 508 then + Result := 0x967A4FB7 + when 509 then + Result := 0x35EECFB1 + when 510 then + Result := 0x2A5110B8 + when 511 then + Result := 0xE2F0AF94 + when 512 then + Result := 0x9D09DEA5 + when 513 then + Result := 0x20255D27 + when 514 then + Result := 0x5771D34B + when 515 then + Result := 0xE1089EE4 + when 516 then + Result := 0x246F330B + when 517 then + Result := 0x8F7CAEE5 + when 518 then + Result := 0xD3064712 + when 519 then + Result := 0x75CAFBEE + when 520 then + Result := 0xB94F7028 + when 521 then + Result := 0xED953666 + when 522 then + Result := 0x5D1975B4 + when 523 then + Result := 0x5AF81271 + when 524 then + Result := 0x13BE2025 + when 525 then + Result := 0x85194659 + when 526 then + Result := 0x30805331 + when 527 then + Result := 0xEC9D46C0 + when 528 then + Result := 0xBC027C36 + when 529 then + Result := 0x2AF84188 + when 530 then + Result := 0xC2141B80 + when 531 then + Result := 0xC02B1E4A + when 532 then + Result := 0x04D36177 + when 533 then + Result := 0xFC50E9D7 + when 534 then + Result := 0x39CE79DA + when 535 then + Result := 0x917E0A00 + when 536 then + Result := 0xEF7A0BF4 + when 537 then + Result := 0xA98BD8D1 + when 538 then + Result := 0x19424DD2 + when 539 then + Result := 0x9439DF1F + when 540 then + Result := 0xC42AF746 + when 541 then + Result := 0xADDBE83E + when 542 then + Result := 0x85221F0D + when 543 then + Result := 0x45563E90 + when 544 then + Result := 0x9095EC52 + when 545 then + Result := 0x77887B25 + when 546 then + Result := 0x8AE46064 + when 547 then + Result := 0xBD43B71A + when 548 then + Result := 0xBB541956 + when 549 then + Result := 0x7366CF9D + when 550 then + Result := 0xEE8E1737 + when 551 then + Result := 0xB5A727C9 + when 552 then + Result := 0x5076B3E7 + when 553 then + Result := 0xFC70BACA + when 554 then + Result := 0xCE135B75 + when 555 then + Result := 0xC4E91AA3 + when 556 then + Result := 0xF0341911 + when 557 then + Result := 0x53430C3F + when 558 then + Result := 0x886B0824 + when 559 then + Result := 0x6BB5B8B7 + when 560 then + Result := 0x33E21254 + when 561 then + Result := 0xF193B456 + when 562 then + Result := 0x5B09617F + when 563 then + Result := 0x215FFF50 + when 564 then + Result := 0x48D97EF1 + when 565 then + Result := 0x356479AB + when 566 then + Result := 0x6EA9DDC4 + when 567 then + Result := 0x0D352746 + when 568 then + Result := 0xA2F5CE43 + when 569 then + Result := 0xB226A1B3 + when 570 then + Result := 0x1329EA3C + when 571 then + Result := 0x7A337CC2 + when 572 then + Result := 0xB5CCE13D + when 573 then + Result := 0x563E3B5B + when 574 then + Result := 0x534E8E8F + when 575 then + Result := 0x561399C9 + when 576 then + Result := 0xE1596392 + when 577 then + Result := 0xB0F03125 + when 578 then + Result := 0x4586645B + when 579 then + Result := 0x1F371847 + when 580 then + Result := 0x94EAABD1 + when 581 then + Result := 0x41F97EDD + when 582 then + Result := 0xE3E5A39B + when 583 then + Result := 0x71C774E2 + when 584 then + Result := 0x507296F4 + when 585 then + Result := 0x5960133B + when 586 then + Result := 0x7852C494 + when 587 then + Result := 0x3F5B2691 + when 588 then + Result := 0xA3F87774 + when 589 then + Result := 0x5A7AF89E + when 590 then + Result := 0x17DA3F28 + when 591 then + Result := 0xE9D9516D + when 592 then + Result := 0xFCC1C1D5 + when 593 then + Result := 0xE4618628 + when 594 then + Result := 0x04081047 + when 595 then + Result := 0xD8E4DB5F + when 596 then + Result := 0xDC380416 + when 597 then + Result := 0x8C4933E2 + when 598 then + Result := 0x95074D53 + when 599 then + Result := 0xB1B0032D + when 600 then + Result := 0xCC8102EA + when 601 then + Result := 0x71641243 + when 602 then + Result := 0x98D6EB6A + when 603 then + Result := 0x90FEC945 + when 604 then + Result := 0xA0914345 + when 605 then + Result := 0x6FAB037D + when 606 then + Result := 0x70F49C4D + when 607 then + Result := 0x05BF5B0E + when 608 then + Result := 0x927AAF7F + when 609 then + Result := 0xA1940F61 + when 610 then + Result := 0xFEE0756F + when 611 then + Result := 0xF815369F + when 612 then + Result := 0x5C00253B + when 613 then + Result := 0xF2B9762F + when 614 then + Result := 0x4AEB3CCC + when 615 then + Result := 0x1069F386 + when 616 then + Result := 0xFBA4E7B9 + when 617 then + Result := 0x70332665 + when 618 then + Result := 0x6BCA810E + when 619 then + Result := 0x85AB8058 + when 620 then + Result := 0xAE4B2B2F + when 621 then + Result := 0x9D120712 + when 622 then + Result := 0xBEE8EACB + when 623 then + Result := 0x776A1112 + end + end +end diff --git a/library/crypto/eapml/random_number_generator.e b/library/crypto/eapml/random_number_generator.e new file mode 100644 index 00000000..7bae1869 --- /dev/null +++ b/library/crypto/eapml/random_number_generator.e @@ -0,0 +1,28 @@ +note + description: "Summary description for {RANDSTRUCT}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Where men cannot freely convey their thoughts to one another, no other liberty is secure. - William E. Hocking (1873-1966), Freedom of the Press, 1947" + +deferred class + RANDOM_NUMBER_GENERATOR + +inherit + LIMB_MANIPULATION + +feature + + randseed (seed: READABLE_INTEGER_X) + deferred + end + + randget (target: SPECIAL [NATURAL_32]; target_offset: INTEGER; count: INTEGER) + require + count = 0 or target.valid_index (target_offset) + count = 0 or target.valid_index (target_offset + bits_to_limbs (count) - 1) + deferred + ensure + target [target_offset + bits_to_limbs (count) - 1] = 0 or else most_significant_one (target [target_offset + bits_to_limbs (count) - 1]) <= bits_top_limb (count) + end +end diff --git a/library/crypto/eapml/readable_integer_x.e b/library/crypto/eapml/readable_integer_x.e new file mode 100644 index 00000000..1902ec8c --- /dev/null +++ b/library/crypto/eapml/readable_integer_x.e @@ -0,0 +1,1741 @@ +note + description: "Functionality to query the status of an arbitrary precision integer" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The urge to save humanity is almost always a false front for the urge to rule. - H.L. Mencken" + +deferred class + READABLE_INTEGER_X + +inherit + ANY + undefine + default_create, + is_equal, + copy + redefine + out + select + out + end + + DEBUG_OUTPUT + undefine + default_create, + is_equal, + copy, + out + redefine + debug_output + end + + NUMERIC + rename + plus as plus_value alias "+", + minus as minus_value alias "-", + product as product_value alias "*", + quotient as quotient_value alias "/", + opposite as opposite_value alias "-" + undefine + default_create, + out + redefine + copy, + is_equal + end + + COMPARABLE + undefine + default_create, + out + redefine + copy, + is_equal, + three_way_comparison + end + + INTEGER_X_ASSIGNMENT + rename + add as add_special, + sub as sub_special, + mul as mul_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_ACCESS + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + tdiv_qr as tdiv_qr_special, + sizeinbase as sizeinbase_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_ARITHMETIC + rename + abs as abs_integer_x, + cmp as cmp_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_COMPARISON + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_LOGIC + rename + add as add_special, + sub as sub_special, + mul as mul_special, + bit_and as bit_and_integer_x, + bit_complement as bit_complement_integer_x, + bit_or as bit_or_integer_x, + bit_test as bit_test_integer_x, + bit_xor as bit_xor_integer_x, + bit_xor_lshift as bit_xor_lshift_integer_x + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_IO + rename + sizeinbase as sizeinbase_special + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_RANDOM + rename + add as add_special, + sub as sub_special, + mul as mul_special, + cmp as cmp_special, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_SIZING + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_NUMBER_THEORY + rename + abs as abs_integer_x, + mod as mod_integer_x, + gcd as gcd_integer_x, + bit_and as bit_and_integer_x, + bit_complement as bit_complement_integer_x, + bit_or as bit_or_integer_x, + bit_test as bit_test_integer_x, + bit_xor as bit_xor_integer_x, + powm as powm_integer_x, + bit_xor_lshift as bit_xor_lshift_integer_x, + invert_gf as invert_gf_integer_x + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + INTEGER_X_DIVISION + rename + abs as abs_integer_x, + cmp as cmp_special, + mod as mod_integer_x, + bit_xor_lshift as bit_xor_lshift_special, + bit_xor as bit_xor_special + export + {NONE} + all + undefine + default_create, + is_equal, + copy, + out + end + + SPECIAL_UTILITY + export + {INTEGER_X_FACILITIES} + all + undefine + default_create, + is_equal, + copy, + out + end + +feature {NONE} -- Initialization + + default_create + -- Initialize `Current' to zero + do + create item.make_filled (0, 1) + count := 0 + ensure then + zero: is_zero + end + + make_set (other: READABLE_INTEGER_X) + -- Initialize `Current' to be a copy of `other' + do + create item.make_filled (0, 0) + set_from_other (other) + ensure + equal: Current ~ other + end + + make_from_integer (i: INTEGER) + -- Initialize `Current' from `i'. + do + default_create + set_from_integer (i) + ensure + set: as_integer = i + end + + make_from_integer_64 (i: INTEGER_64) + -- Initialize `Current' from `i'. + do + default_create + set_from_integer_64 (i) + ensure + set: as_integer_64 = i + end + + make_from_integer_32 (i: INTEGER_32) + -- Initialize `Current' from `i'. + do + default_create + set_from_integer_32 (i) + ensure + set: as_integer_32 = i + end + + make_from_integer_16 (i: INTEGER_16) + -- Initialize `Current' from `i'. + do + default_create + set_from_integer_16 (i) + ensure + set: as_integer_16 = i + end + + make_from_integer_8 (i: INTEGER_8) + -- Initialize `Current' from `i'. + do + default_create + set_from_integer_8 (i) + ensure + set: as_integer_8 = i + end + + make_from_natural (n: NATURAL) + -- Initialize `Current' from `n'. + do + default_create + set_from_natural (n) + ensure + set: as_natural = n + end + + make_from_natural_64 (n: NATURAL_64) + -- Initialize `Current' from `n'. + do + default_create + set_from_natural_64 (n) + ensure + set: as_natural_64 = n + end + + make_from_natural_32 (n: NATURAL_32) + -- Initialize `Current' from `n'. + do + default_create + set_from_natural_32 (n) + ensure + set: as_natural_32 = n + end + + make_from_natural_16 (n: NATURAL_16) + -- Initialize `Current' from `n'. + do + default_create + set_from_natural_16 (n) + ensure + set: as_natural_16 = n + end + + make_from_natural_8 (n: NATURAL_8) + -- Initialize `Current' from `n'. + do + default_create + set_from_natural_8 (n) + ensure + set: as_natural_8 = n + end + + make_from_string (s: STRING) + -- Initialize `Current' from `s' where `s' is a base 10 string + require + s_not_empty: not s.is_empty + do + default_create + set_str (Current, s, 10) + end + + make_from_hex_string (s: STRING) + -- Initialize `Current' from `s' where `s' is a base 16 string + require + s_not_empty: not s.is_empty + do + default_create + set_str (Current, s, 16) + end + + make_from_string_base (s: STRING base: INTEGER) + -- Initialize `Current' from `s' where `s' is a string of base `base' + require + s_not_empty: not s.is_empty + base_too_small: base >= 2 + base_too_big: base <= 62 + do + default_create + set_str (Current, s, base) + end + + make_random (bits_a: INTEGER) + -- Initialize as a random number of `bits_a' bits + require + valid_bits: bits_a > 0 + do + default_create + set_random (bits_a) + ensure + correct_bits: bits <= bits_a + end + + make_random_prime (bits_a: INTEGER) + -- Initialise a random number of `bits_a' bits that is probably prime + require + valid_bits: bits_a > 0 + do + default_create + from + set_random (bits_a) + until + is_probably_prime + loop + set_random (bits_a) + end + ensure + prime: is_probably_prime + correct_bits: bits <= bits_a + end + + make_from_bytes (bytes_array: SPECIAL[NATURAL_8] first: INTEGER last: INTEGER) + -- Initialize from byte array + require + last_after_first: last >= first + valid_offset: bytes_array.valid_index (first) + valid_end: bytes_array.valid_index (last) + do + default_create + input (Current, last - first + 1, 1, 1, -1, bytes_array, first) + end + + make_random_max (max_value: like Current) + --Generate a uniform random integer in the range 0 to max_value-1, inclusive. + require + positive_max: max_value.is_positive + do + default_create + urandomm (Current, random_state, max_value) + ensure + valid_range: Current < max_value + end + + make_limbs (limbs: INTEGER) + -- Initialize `Current' with space for `limbs' limbs in the internal representation + do + create item.make_filled (0, limbs) + count := 0 + ensure + is_zero + end + + make_bits (bits_a: INTEGER) + do + create item.make_filled (0, (bits_a + (limb_bits - 1)) // limb_bits) + count := 0 + ensure + is_zero + end + +feature -- Constants + + one: like Current + -- Neutral element for "*" and "/" + deferred + end + + zero: like Current + -- Neutral element for "+" and "-" + deferred + end + +feature -- Comparison + + is_less alias "<" (other: like Current): BOOLEAN + -- Is current object less than `other'? + do + Result := three_way_comparison (other) < 0 + end + + is_equal (other: like Current): BOOLEAN + -- Is `other' attached to an object considered + -- equal to current object? + do + Result := three_way_comparison (other) = 0 + end + + three_way_comparison (other: like Current): INTEGER + -- Perform a three way comparison between `Current' and `other' + do + Result := compare (Current, other).three_way_comparison (0) + end + +feature -- Measurement + + bytes: INTEGER + -- Minimum number of bytes the absolute value of this number would occupy + do + Result := (bits + 7).bit_and (0xfffffff8).bit_shift_right (3) + end + + bits: INTEGER + -- Minimum number of bits the absolute value of this number would occupy + do + Result := size_in_base (2) + ensure + valid_result: Result >= 1 + end + +feature -- Status report + + divisible (other: like Current): BOOLEAN + -- May `Current' be divided by `other'? + do + Result := not other.is_zero + end + + exponentiable (other: NATURAL_32_REF): BOOLEAN + -- May `Current' be elevated to the power `other'? + do + Result := True + end + + fits_natural: BOOLEAN + -- Does `Current' fit in a {NATURAL} without truncation? + do + Result := fits_natural_32 + end + + fits_natural_64: BOOLEAN + -- Does `Current' fit in a {NATURAL_64} without truncation? + local + n: INTEGER + do + resize (2) + n := count + Result := n >= 0 and n <= 2 + end + + fits_natural_32: BOOLEAN + -- Does `Current' fit in a {NATURAL_32} without truncation? + local + n: INTEGER + do + n := count + Result := n = 0 or n = 1 + end + + fits_natural_16: BOOLEAN + -- Does `Current' fit in a {NATURAL_16} without truncation? + local + n: INTEGER_32 + do + n := count + Result := n = 0 or (n = 1 and then item [0] <= (0).to_natural_16.max_value) + end + + fits_natural_8: BOOLEAN + -- Does `Current' fit in a {NATURAL_8} without truncation? + local + n: INTEGER_32 + do + n := count + Result := n = 0 or (n = 1 and then item [0] <= (0).to_natural_8.max_value) + end + + fits_integer: BOOLEAN + -- Does `Current' fit in an {INTEGER} without truncation? + do + Result := fits_integer_32 + end + + fits_integer_64: BOOLEAN + -- Does `Current' fit in an {INTEGER_64} without truncation? + local + n: INTEGER + limb1: NATURAL_32 + limb2: NATURAL_32 + do + n := count + limb1 := item [0] + if n = 0 or n = 1 or n = -1 then + Result := True + elseif n = 2 then + limb2 := item [1] + Result := not limb2.bit_test (31) + elseif n = -2 then + limb2 := item [1] + if limb2.bit_test (31) then + Result := limb2.bit_and (0x7fffffff) = 0 and limb1 = 0 + else + Result := True + end + end + end + + fits_integer_32: BOOLEAN + -- Does `Current' fit in an {INTEGER_32} without truncation? + local + n: INTEGER_32 + limb: NATURAL_32 + do + n := count + limb := item [0] + if + n = 0 + then + Result := True + elseif n = 1 then + Result := not limb.bit_test (31) + elseif n = -1 then + if limb.bit_test (31) then + Result := limb.bit_and (0x7fffffff) = 0 + else + Result := True + end + end + end + + fits_integer_16: BOOLEAN + -- Does `Current' fit in an {INTEGER_16} without truncation? + local + n: INTEGER + limb: NATURAL_32 + do + n := count + limb := item [0] + if n = 0 then + Result := True + elseif n = 1 then + Result := limb <= (0).to_integer_16.max_value.to_natural_32 + elseif n = -1 then + Result := limb <= (0).to_integer_16.min_value.to_integer_32.abs.to_natural_32 + else + Result := False + end + end + + fits_integer_8: BOOLEAN + -- Does `Current' fit in an {INTEGER_8} without truncation? + local + n: INTEGER + limb: NATURAL_32 + do + n := count + limb := item [0] + if n = 0 then + Result := True + elseif n = 1 then + Result := limb <= (0).to_integer_8.max_value.to_natural_32 + elseif n = -1 then + Result := limb <= (0).to_integer_8.min_value.to_integer_32.abs.to_natural_32 + end + end + + is_odd: BOOLEAN + -- Is `Current' odd + do + Result := count /= 0 and then item [0].bit_test (0) + end + + is_even: BOOLEAN + -- Is `Current' even? + do + Result := not is_odd + end + + is_zero: BOOLEAN + -- Is `Current' equal to zero + do + Result := sign = 0 + end + + is_positive: BOOLEAN + -- Is `Current' positive + do + Result := sign = 1 + end + + is_negative: BOOLEAN + -- Is `Current' negative + do + Result := sign = -1 + end + + sign: INTEGER + -- Return the sign of `Current' where -1 is negative, 0 is zero, and 1 is positive + do + Result := count.three_way_comparison (0) + ensure + is_positive implies (Result = 1) + is_zero implies (Result = 0) + is_negative implies (Result = -1) + end + + size_in_base (base: INTEGER): INTEGER + -- What is the size of the string representing the absolute value of `Current' in base `base' + require + base_too_small: base >= 2 + base_too_big: base <= 62 + do + Result := sizeinbase (Current, base) + end + +feature -- Primality testing + + is_composite: BOOLEAN + -- Is `Current' a composite number? + do + Result := probab_prime_p (Current, 10) = 0 + end + + is_prime: BOOLEAN + -- Is `Current' definitely a prime number? + do + Result := probab_prime_p (Current, 10) = 2 + end + + is_probably_prime: BOOLEAN + -- Is `Current' probably a prime number? + -- May return `False' if `Current' is actually prime. + do + Result := probab_prime_p (Current, 10) > 0 + end + +feature {INTEGER_X_FACILITIES}-- Element change + + set_from_other (other: READABLE_INTEGER_X) + local + other_count: INTEGER + do + other_count := other.count + resize (other_count) + item.copy_data (other.item, 0, 0, other_count) + count := other_count + end + + set_from_integer (value_a: INTEGER) + -- Initialize `Current' from `value_a'. + do + set_from_integer_32 (value_a) + ensure + value_a > 0 implies count = 1 + value_a = 0 implies count = 0 + value_a < 0 implies count = -1 + fits_integer + as_integer = value_a + end + + set_from_integer_64 (value_a: INTEGER_64) + -- Initialize `Current' from `value_a' + local + new_value: NATURAL_64 + upper_limb: NATURAL_32 + new_count: INTEGER + do + resize (2) + new_value := value_a.abs.to_natural_64 + item [0] := new_value.to_natural_32 + upper_limb := (new_value |>> 32).to_natural_32 + item [1] := upper_limb + new_count := value_a.three_way_comparison (0) + new_count := new_count * ((upper_limb /= 0).to_integer + 1) + count_set (new_count) + ensure + value_a > 0 implies (count = 1 or count = 2) + value_a = 0 implies (count = 0) + value_a < 0 implies (count = -1 or count = -2) + fits_integer_64 + as_integer_64 = value_a + end + + set_from_integer_32 (value_a: INTEGER_32) + -- Initialize `Current' from `value_a'. + local + limb: NATURAL_32 + do + if value_a < 0 then + limb := value_a.to_natural_32.bit_not + 1 + else + limb := value_a.to_natural_32 + end + item [0] := limb + count_set (value_a.three_way_comparison (0)) + ensure + value_a > 0 implies count = 1 + value_a = 0 implies count = 0 + value_a < 0 implies count = -1 + fits_integer_32 + as_integer_32 = value_a + end + + set_from_integer_16 (value_a: INTEGER_16) + -- Initialize `Current' from `value_a'. + local + limb: NATURAL_32 + do + if value_a < 0 then + limb := value_a.to_natural_32.bit_not + 1 + else + limb := value_a.to_natural_32 + end + item [0] := limb + count_set (value_a.three_way_comparison (0)) + ensure + value_a > 0 implies count = 1 + value_a = 0 implies count = 0 + value_a < 0 implies count = -1 + fits_integer_16 + as_integer_16 = value_a + end + + set_from_integer_8 (value_a: INTEGER_8) + -- Initialize `Current' from `value_a'. + local + limb: NATURAL_32 + do + if value_a < 0 then + limb := value_a.to_natural_32.bit_not + 1 + else + limb := value_a.to_natural_32 + end + item [0] := limb + count_set (value_a.three_way_comparison (0)) + ensure + value_a > 0 implies count = 1 + value_a = 0 implies count = 0 + value_a < 0 implies count = -1 + fits_integer_8 + as_integer_8 = value_a + end + + set_from_natural (value_a: NATURAL) + -- Initialize `Current' from `value_a'. + do + set_from_natural_32 (value_a) + ensure + value_a = 0 implies count = 0 + value_a /= 0 implies count = 1 + fits_natural + as_natural = value_a + end + + set_from_natural_64 (value_a: NATURAL_64) + -- Initialize `Current' from `value_a'. + local + upper_limb: NATURAL_32 + new_count: INTEGER + do + resize (2) + item [0] := value_a.to_natural_32 + upper_limb := (value_a |>> 32).to_natural_32 + item [1] := upper_limb + new_count := value_a.three_way_comparison (0) + new_count := new_count + (upper_limb /= 0).to_integer + count_set (new_count) + ensure + value_a = 0 implies count = 0 + value_a /= 0 implies (count = 1 or count = 2) + fits_natural_64 + as_natural_64 = value_a + end + + set_from_natural_32 (value_a: NATURAL_32) + -- Initialize `Current' from `value_a'. + do + item [0] := value_a + if + value_a /= 0 + then + count_set (1) + else + count_set (0) + end + ensure + value_a = 0 implies count = 0 + value_a /= 0 implies count = 1 + fits_natural_32 + as_natural_32 = value_a + end + + set_from_natural_16 (value_a: NATURAL_16) + -- Initialize `Current' from `value_a'. + do + item [0] := value_a.to_natural_32 + if + value_a /= 0 + then + count_set (1) + else + count_set (0) + end + ensure + value_a = 0 implies count = 0 + value_a /= 0 implies count = 1 + fits_natural_16 + as_natural_16 = value_a + end + + set_from_natural_8 (value_a: NATURAL_8) + -- Initialize `Current' from `value_a'. + do + item [0] := value_a.to_natural_32 + if + value_a /= 0 + then + count_set (1) + else + count_set (0) + end + ensure + value_a = 0 implies count = 0 + value_a /= 0 implies count = 1 + fits_natural_8 + as_natural = value_a + end + + set_from_string (s: STRING) + -- Initialize `Current' from `s' where `s' is a base 10 string + require + s_not_empty: not s.is_empty + do + set_str (Current, s, 10) + end + + set_random (bits_a: INTEGER) + -- Initialize `Current' to random bits up to `bits_a' bits + require + valid_bits: bits_a >= 1 + do + urandomb (Current, random_state, bits_a) + ensure + bits <= bits_a + end + +feature -- Conversion with possible truncation. + -- Negatives wrap around in the negatives, non-negatives wrap around in the non-negatives + + as_integer: INTEGER + -- Return the value of `Current' truncated to an {INTEGER} + do + Result := as_integer_32 + end + + as_integer_64: INTEGER_64 + -- Return the value of `Current' truncated to an {INTEGER_64} + local + size: INTEGER + unsigned_result: NATURAL_64 + do + size := count + if size > 1 then + unsigned_result := item [1].to_natural_64.bit_shift_left (32) + end + unsigned_result := unsigned_result.bit_or (item [0].to_natural_64) + if size > 0 then + Result := unsigned_result.to_integer_64.bit_and (0x7fff_ffff_ffff_ffff) + elseif size < 0 then + Result := (unsigned_result.to_integer_64 - 1).bit_and (0x7fff_ffff_ffff_ffff).bit_not + else + Result := 0 + end + end + + as_integer_32: INTEGER_32 + -- Return the value of `Current' truncated to an {INTEGER_32} + local + size: INTEGER + zl: NATURAL_32 + do + size := count + zl := item [0] + if size > 0 then + Result := zl.to_integer_32.bit_and (0x7fffffff) + elseif size < 0 then + Result := (zl.to_integer_32 - 1).bit_and (0x7fffffff).bit_not + else + Result := 0 + end + end + + as_integer_16: INTEGER_16 + -- Return the value of `Current' truncated to an {INTEGER_16} + local + size: INTEGER + limb: NATURAL_32 + do + size := count + limb := item [0] + if size > 0 then + Result := limb.to_integer_16.bit_and (0x7fff) + elseif size < 0 then + Result := (limb.to_integer_16 - 1).bit_and (0x7fff).bit_not + else + Result := 0 + end + end + + as_integer_8: INTEGER_8 + -- Return the value of `Current' truncated to an {INTEGER_8} + local + size: INTEGER + limb: NATURAL_32 + do + size := count + limb := item [0] + if size > 0 then + Result := limb.to_integer_8.bit_and (0x7f) + elseif size < 0 then + Result := (limb.to_integer_8 - 1).bit_and (0x7f).bit_not + else + Result := 0 + end + end + + as_natural: NATURAL + -- Return the value of the absolute value of `Current' truncated to a {NATURAL} + do + Result := as_natural_32 + end + + as_natural_64: NATURAL_64 + -- Return the value of the absolute value of `Current' truncated to a {NATURAL_64} + local + n: INTEGER + data: SPECIAL [NATURAL_32] + do + n := count + data := item + if + n = 0 + then + Result := 0 + elseif n = 1 then + Result := data [0] + else + Result := data [1] + Result := Result |<< 32 + Result := Result.bit_or (data [0]) + end + end + + as_natural_32: NATURAL_32 + -- Return the value of the absolute value of `Current' truncated to a {NATURAL_32} + do + if + count = 0 + then + Result := 0 + else + Result := item [0] + end + end + + as_natural_16: NATURAL_16 + -- Return the value of the absolute value of `Current' truncated to a {NATURAL_16} + do + if + count = 0 + then + Result := 0 + else + Result := item [0].as_natural_16 + end + end + + as_natural_8: NATURAL_8 + -- Return the value of the absolute value of `Current' truncated to a {NATURAL_8} + do + if + count = 0 + then + Result := 0 + else + Result := item [0].as_natural_8 + end + end + +feature -- Lossless conversion + + to_integer: INTEGER + -- Return the value of `Current' as an {INTEGER} + require + fits: fits_integer_32 + do + Result := as_integer_32 + ensure + Current ~ (create {INTEGER_X}.make_from_integer (Result)) + end + + to_integer_64: INTEGER_64 + -- Return the value of `Current' as an {INTEGER_64} + require + fits: fits_integer_64 + do + Result := as_integer_64 + ensure + Current ~ (create {INTEGER_X}.make_from_integer_64 (Result)) + end + + to_integer_32: INTEGER_32 + -- Return the value of `Current' as an {INTEGER_32} + require + fits: fits_integer_32 + do + Result := as_integer_32 + ensure + Current ~ (create {INTEGER_X}.make_from_integer_32 (Result)) + end + + to_integer_16: INTEGER_16 + -- Return the value of `Current' as an {INTEGER_16} + require + fits: fits_integer_16 + do + Result := as_integer_16 + ensure + Current ~ (create {INTEGER_X}.make_from_integer_16 (Result)) + end + + to_integer_8: INTEGER_8 + -- Return the value of `Current' as an {INTEGER_8} + require + fits: fits_integer_8 + do + Result := as_integer_8 + ensure + Current ~ (create {INTEGER_X}.make_from_integer_8 (Result)) + end + + to_natural: NATURAL_32 + -- Return the value of `Current' as a {NATURAL} + require + fits: fits_natural + do + Result := to_natural_32 + ensure + Current ~ (create {INTEGER_X}.make_from_natural (Result)) + end + + to_natural_64: NATURAL_64 + -- Return the value of `Current' as a {NATURAL_64} + require + fits: fits_natural_64 + do + Result := as_natural_64 + ensure + Current ~ (create {INTEGER_X}.make_from_natural_64 (Result)) + end + + to_natural_32: NATURAL_32 + -- Return the value of `Current' as a {NATURAL_32} + require + fits: fits_natural_32 + do + Result := as_natural_32 + ensure + Current ~ (create {INTEGER_X}.make_from_natural_32 (Result)) + end + + to_natural_16: NATURAL_16 + -- Return the value of `Current' as a {NATURAL_16} + require + fits: fits_natural_16 + do + Result := as_natural_16 + ensure + Current ~ (create {INTEGER_X}.make_from_natural_16 (Result)) + end + + to_natural_8: NATURAL_8 + -- Return the value of `Current' as a {NATURAL_8} + require + fits: fits_natural_8 + do + Result := as_natural_8 + ensure + Current ~ (create {INTEGER_X}.make_from_natural_8 (Result)) + end + + to_bytes (target: SPECIAL [NATURAL_8] offset: INTEGER) + -- Convert the absolute value of `Current' to a byte array + require + big_enough: bytes <= target.upper - offset + 1 + local + junk: TUPLE [junk: INTEGER] + do + create junk + output (target, offset, junk, 1, 1, -1, Current) + ensure + reversable: (create {INTEGER_X}.make_from_bytes (target, offset, offset + bytes - 1)) ~ Current + end + + as_bytes: SPECIAL[NATURAL_8] + -- Convert the absolute value of `Current' to a byte array + do + create Result.make_filled (0, bytes) + to_bytes (Result, Result.lower) + ensure + reversable: (create {INTEGER_X}.make_from_bytes (Result, Result.lower, Result.upper)) ~ Current + end + + to_fixed_width_byte_array (target: SPECIAL [NATURAL_8] first: INTEGER last: INTEGER) + require + valid_first: target.valid_index (first) + valid_last: target.valid_index (last) + enough_space: last - bytes + 1 >= first + local + junk: TUPLE [junk: INTEGER_32] + do + create junk + target.fill_with (0x0, first, last) + output (target, first + (last - first - bytes + 1), junk, 1, 1, -1, Current) + ensure + reversable: (create {INTEGER_X}.make_from_bytes (target, first, last)) ~ Current + end + + as_fixed_width_byte_array (byte_size: INTEGER): SPECIAL[NATURAL_8] + -- Convert the absolute value of `Current' to a byte array of `byte_size' bytes + require + enough_space: bytes <= byte_size + do + create Result.make_filled (0, byte_size) + to_fixed_width_byte_array (Result, 0, byte_size - 1) + ensure + reversable: (create {INTEGER_X}.make_from_bytes (Result, Result.lower, Result.upper)) ~ Current + end + +feature -- Duplication + + copy (other: like Current) + -- Update `Current' to be a copy of `other' + local + usize: INTEGER + size: INTEGER + do + usize := other.count + size := usize.abs + resize (size) + item.copy_data (other.item, 0, 0, size) + count := usize + end + +feature {INTEGER_X_FACILITIES}-- Basic operations stateful + + abs + -- Modify `Current' to be non-negative + do + abs_integer_x (Current, Current) + ensure + non_negative: not is_negative + end + + plus (other: like Current) + -- Modify `Current' to be the sum of `Current' and `other' + do + add (Current, Current, other) + end + + minus (other: like Current) + -- Modify `Current' to be the subtraction of `Current' and `other' + do + sub (Current, Current, other) + end + + product (other: like Current) + -- Modify `Current' to be the product of `Current' and `other' + do + mul (Current, Current, other) + end + + quotient (other: like Current) + -- Modify `Current' to be the quotient by truncation division of `Current' by `other' + do + tdiv_q (Current, Current, other) + end + + opposite + -- Modify `Current' to be the opposite sign or do nothing if `Current'.is_zero + do + neg (Current, Current) + end + +feature -- Basic operations stateless + abs_value: like Current + -- Return the absolute value of `Current' + do + Result := identity + Result.abs + ensure + non_negative: not Result.is_negative + same_absolute_value: (Result ~ (Current)) or (Result ~ (-Current)) + end + + plus_value alias "+" (other: like Current): like Current + -- Return the sum of `Current' and `other' + do + Result := identity + Result.plus (other) + ensure then + Result - Current ~ other + Result - other ~ Current + end + + minus_value alias "-" (other: like Current): like Current + -- Return the subtraction of `Current' and `other' + do + Result := identity + Result.minus (other) + ensure then + Result + other ~ Current + Current - Result ~ other + end + + product_value alias "*" (other: like Current): like Current + -- Return the product of `Current' and `other' + do + Result := identity + Result.product (other) + ensure then + Result / Current ~ other + Result / other ~ Current + end + + quotient_value alias "/" (other: like Current): like Current + -- Return the integer quotient by truncation division of `Current' by `other' + do + Result := identity + Result.quotient (other) + end + + identity alias "+": like Current + -- Return the identity of `Current' + do + Result := deep_twin + end + + opposite_value alias "-": like Current + -- Return the negative of `Current' + do + Result := identity + Result.opposite + end + +feature {INTEGER_X_FACILITIES}-- Bit operations stateful + + bit_complement (bit_a: INTEGER) + -- Modify `Current' to have bit `bit_a' complemented + do + bit_complement_integer_x (Current, bit_a) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_and (other: like Current) + -- Modify `Current' to be the bitwise AND of `Current' and `other' + do + bit_and_integer_x (Current, Current, other) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_or (other: like Current) + -- Modify `Current' to be the bitwise OR of `Current' and `other' + do + bit_or_integer_x (Current, Current, other) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_xor (other: like Current) + -- Modify `Current' to be the bitwise XOR of `Current' and `other' + do + bit_xor_integer_x (Current, Current, other) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_not + -- Modify `Current' to be a bitwise NOT of `Current' + do + bit_one_complement (Current, Current) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_xor_left_shift (other: like Current left_shift_bits: INTEGER) + -- Modify `Current' to be the bitwise XOR of `Current' and (`other' shifted left `left_shift_bits' bits) + do + bit_xor_lshift_integer_x (Current, Current, other, left_shift_bits) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_shift_right (bits_a: INTEGER) + -- Modify `Current' to be bit shifted right `bits_a' bits + do + tdiv_q_2exp (Current, Current, bits_a) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_shift_left (bits_a: INTEGER) + -- Modify `Current' to be bit shifted left `bits_a' bits + do + mul_2exp (Current, Current, bits_a) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + set_bit (value: BOOLEAN; bit_a: INTEGER) + -- Modify `Current' and set bit `bit_a' if `value' is True + do + if value then + bit_set (Current, bit_a) + else + bit_clear (Current, bit_a) + end + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + +feature -- Bit operations stateless + -- All bit operations are performed as if the number was stored in two-complement format + + bit_complement_value (bit_a: INTEGER): like Current + -- Return a copy of `Current' with bit `bit_a' complemented + require + valid_i: bit_a >= 0 + do + Result := identity + Result.bit_complement (bit_a) + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + + bit_and_value alias "&" (other: like Current): like Current + -- Return the bitwise AND of `Current' and `other' + do + Result := identity + Result.bit_and (other) + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + + bit_or_value alias "|" (other: like Current): like Current + -- Return the bitwise OR of `Current' and `other' + do + Result := identity + Result.bit_or (other) + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + + bit_xor_value (other: like Current): like Current + -- Return the bitwise XOR of `Current' and `other' + do + Result := identity + Result.bit_xor (other) + ensure + Result.bit_xor_value (Current) ~ other + Result.bit_xor_value (other) ~ Current + end + + bit_xor_left_shift_value (other: like Current left_shift_bits: INTEGER): like Current + -- Return the bitwise XOR of `Current' and (`other' shifted left `left_shift_bits' bits) + do + Result := identity + Result.bit_xor_left_shift (other, left_shift_bits) + ensure + is_negative implies not old is_positive + is_positive implies not old is_negative + end + + bit_not_value: like Current + -- Return the a bitwise NOT of `Current' + do + Result := identity + Result.bit_not + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + + bit_shift_left_value alias "|<<" (bits_a: INTEGER): like Current + -- Return `Current' bit shifted left `bits_a' bits + require + n_nonnegative: bits_a >= 0 + do + Result := identity + Result.bit_shift_left (bits_a) + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + + bit_shift_right_value alias "|>>" (bits_a: INTEGER): like Current + -- Return `Current' bit shifted right `bits_a' bits, truncating lower bits + require + n_nonnegative: bits_a >= 0 + do + Result := identity + Result.bit_shift_right (bits_a) + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + + bit_test (bit_a: INTEGER): BOOLEAN + -- Is bit at position `bit_a' set + require + n_nonnegative: bit_a >= 0 + do + Result := bit_test_integer_x (Current, bit_a) + end + + set_bit_value (value: BOOLEAN; bit_a: INTEGER): like Current + -- Return a copy of `Current' with bit `bit_a' set if `value' is True + require + n_nonnegative: bit_a >= 0 + do + Result := identity + Result.set_bit (value, bit_a) + ensure + is_negative implies not Result.is_positive + is_positive implies not Result.is_negative + end + +feature {INTEGER_X_FACILITIES}-- Discrete operations stateful + + powm (exponent: like Current; modulus: like Current) + -- Modify `Current' to be (`Current' raised to `exponent') modulo `modulus' + -- Negative `exponent' is supported if an inverse base^-1 mod mod exists {INTEGER_X}.invert + -- If `exponent' does not have an inverse modulo `modulus', an {INVERSE_EXCEPTION} will be raised + do + powm_integer_x (Current, Current, exponent, modulus) + end + + inverse (modulus: like Current) + -- Set `Current' to be the inverse of `Current' modulo `modulus' + -- If `Current' does not have an inverse modulo `modulus', an {INVERSE_EXCEPTION} will be raised + local + has_inverse: BOOLEAN + do + has_inverse := invert (Current, Current, modulus) + if not has_inverse then + (create {INVERSE_EXCEPTION}).raise + end + ensure + coprime: coprime (modulus) + end + + modulo (mod: like Current) + -- Set `Current' to `Current' modulo `modulus' + do + mod_integer_x (Current, Current, mod) + end + + gcd (op1: like Current; op2: like Current) + -- Set `Current' to the Greatest Common Divisor between `op1' and `op2' + do + gcd_integer_x (Current, op1, op2) + ensure + positive_result: Current.is_positive + op1.coprime (op2) = (Current ~ one) + end + +feature -- Discrete operations stateless + + powm_value (exponent: like Current; modulus: like Current): like Current + -- Return (`Current' raised to `exponent') modulo `modulus'. + -- Negative `exponent' is supported if an inverse base^-1 mod mod exists {INTEGER_X}.invert + -- If an inverse doesn't exist then a divide by zero is raised + do + Result := identity + Result.powm (exponent, modulus) + end + + inverse_value (modulus: like Current): like Current + -- Return the inverse of `Current' modulo `modulus' + -- If `Current' does not have an inverse modulo `modulus', an {INVERSE_EXCEPTION} will be raised + do + Result := identity + Result.inverse (modulus) + ensure + correct_result: ((Result * Current) \\ modulus) ~ (one) + coprime: coprime (modulus) + end + + modulo_value alias "\\" (modulus: like Current): like Current + -- Return `Current' modulo `modulus' + do + Result := identity + Result.modulo (modulus) + end + + gcd_value (other: like Current): like Current + -- Return the Greatest Common Divisor between `Current' and `other' + do + Result := identity + Result.gcd (Current, other) + ensure + positive_result: Result.is_positive + coprime (other) = (Result ~ one) + end + + coprime (other: like Current): BOOLEAN + -- Are `Current' and `other' coprime? + do + Result := gcd_value (other) ~ (one) + ensure + Result = (gcd_value (other) ~ (one)) + end + +feature {INTEGER_X_FACILITIES}-- Galois field arithmetic stateful + invert_gf (other: like Current) + require + not is_negative + not other.is_negative + do + invert_gf_integer_x (Current, Current, other) + ensure + not is_negative + other.identity ~ old other.identity + end + +feature -- Galois field arithmetic stateless + invert_gf_value (other: like Current): like Current + require + not is_negative + not other.is_negative + do + Result := identity + Result.invert_gf (other) + ensure + not Result.is_negative + identity ~ old identity + other.identity ~ old other.identity + end + +feature -- Output + + debug_output: STRING + -- Return a debug string of `Current' + do + Result := out_hex + end + + out: STRING + -- Return a hexicedimal representation of the value of `Current' + do + Result := out_hex + end + + out_decimal: STRING + -- Return a decimal representation of the value of `Current' + do + Result := out_base (10) + end + + out_hex: STRING + -- Return a hexidecimal representation ofthe value of `Current' + do + Result := out_base (16) + end + + out_base (base: INTEGER_32): STRING + -- Return a representation of `Current' in base `base' + require + base_too_small: base >= 2 + base_too_big: base <= 62 + do + Result := get_string (Current, base) + end + +feature {NONE} -- Implementation + + random_state: RANDOM_NUMBER_GENERATOR + once + create {LINEAR_CONGRUENTIAL_RNG}Result.make (32) + end + +feature {INTEGER_X_FACILITIES} + + normalized: BOOLEAN + -- Does `count' represent the number of non-zero limbs in `item' + do + Result := normalize (item, 0, count) = count + end + + components_set (item_value: SPECIAL [NATURAL_32] count_value: INTEGER) + -- Set `item' and `count' simultaneously + do + item_set (item_value) + count_set (count_value) + end + + capacity: INTEGER + -- Number of limbs allocated in `item' + do + Result := item.capacity + end + + item: SPECIAL [NATURAL_32] assign item_set + -- Backing storage for the number + + item_set (value_a: SPECIAL [NATURAL_32]) + -- Change `item' to `value_a' + do + item := value_a + end + + count: INTEGER assign count_set + -- `count.abs' is the number of limbs in `item' that have meaning + -- If `size' is negative this is a negative number. + attribute + end + + count_set (value_a: INTEGER) + -- Change `count' to `value_a' + do + count := value_a + end + + resize (new_alloc: INTEGER) + -- Change the space for integer to at least `new_alloc' limbs. + local + allocate_size: INTEGER_32 + do + if new_alloc > capacity then + allocate_size := new_alloc.max (1) + item := item.aliased_resized_area_with_default (0, allocate_size) + end + end + + set_components (item_a: SPECIAL [NATURAL_32] count_a: INTEGER) + do + item := item_a + count := count_a + end + +invariant +-- normalized: normalized + capacity >= 1 + count <= item.count + item.count = item.capacity +end diff --git a/library/crypto/eapml/tests/TODO.txt b/library/crypto/eapml/tests/TODO.txt new file mode 100644 index 00000000..a64bb456 --- /dev/null +++ b/library/crypto/eapml/tests/TODO.txt @@ -0,0 +1,37 @@ +Test suite order - + +-Interfaces must be tested first (string conversions, Eiffel native construction conversions, etc, using known good large numbers verified by other big number libraries. +(If we don't have at least this then nothing else can be trusted) + +-Integer Interfaces +-Real Interfaces + * Real MPF + * Real MPFR +-Rational +-Complex Integer +-Complex Complex Real + * Complex Real MPF + * Complex Real MPFR +-Complex Rational + + + +-Test arithmetic functions for each eiffel MP constrcts using known values/solutions for "big" numbers and checking using previously tested known-good interfaces. + + *Test arithmetic operations between similar types of MP constructs + *Test arithmetic operations between different types of MP constructs + + +TODO: +Reformat test suite order +Start testing interfaces +-Integer Interfaces +-Real Interfaces + * Real MPF + * Real MPFR +-Rational +-Complex Integer +-Complex Complex Real + * Complex Real MPF + * Complex Real MPFR +-Complex Rational diff --git a/library/crypto/eapml/tests/test.e b/library/crypto/eapml/tests/test.e new file mode 100644 index 00000000..6d58040f --- /dev/null +++ b/library/crypto/eapml/tests/test.e @@ -0,0 +1,43 @@ +note + description : "Library unit test root class" + date : "$Date: 2008-12-29 15:41:59 -0800 (Mon, 29 Dec 2008) $" + revision : "$Revision: 76432 $" + +class + TEST + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + local + do + end + + test1: detachable TEST_INTEGER_X + test2: detachable TEST_INTEGER_FUNCTIONS + test3: detachable TEST_INTEGER_X_ASSIGNMENT + test4: detachable TEST_SPECIAL_ARITHMETIC + test5: detachable TEST_SPECIAL_DIVISION + test6: detachable TEST_SPECIAL_LOGIC + test7: detachable TEST_SPECIAL_NUMBER_THEORETIC + test9: detachable TEST_RANDSTRUCT_LC + test10: detachable TEST_RANDSTRUCT_MT + test11: detachable TEST_INTEGER_X_RANDOM + test12: detachable TEST_INTEGER_X_ACCESS + test13: detachable TEST_INTEGER_X_IO + test14: detachable TEST_INTEGER_X_NUMBER_THEORY + test15: detachable TEST_INTEGER_X_ARITHMETIC + test16: detachable TEST_SPECIAL_GCD + test17: detachable TEST_INTEGER_X_DIVISION + test18: detachable TEST_INTEGER_X_GCD + test19: detachable TEST_INTEGER_X_LOGIC + test20: detachable TEST_LIMB_MANIPULATION + test21: detachable IMMUTABLE_INTEGER_X + test22: detachable INTEGER_X +end diff --git a/library/crypto/eapml/tests/test_integer_functions.e b/library/crypto/eapml/tests/test_integer_functions.e new file mode 100644 index 00000000..58317365 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_functions.e @@ -0,0 +1,19 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + TEST_INTEGER_FUNCTIONS + +inherit + EQA_TEST_SET + +feature -- Test routines +end + + diff --git a/library/crypto/eapml/tests/test_integer_x.e b/library/crypto/eapml/tests/test_integer_x.e new file mode 100644 index 00000000..f0a9ad75 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x.e @@ -0,0 +1,557 @@ +note + description: "[ + Eiffel tests that can be executed by testing tool. + ]" + author: "EiffelStudio test wizard" + date: "$Date$" + revision: "$Revision$" + testing: "type/manual" + +class + TEST_INTEGER_X + +inherit + EQA_TEST_SET + INTEGER_X_ASSIGNMENT + undefine + default_create + end + +feature -- Basic operations tests + test_init + local + one: INTEGER_X + do + create one + end + + test_default_zero + local + one: INTEGER_X + do + create one + assert ("{INTEGER_X}.default_create", one.to_integer_32 = 0) + end + + test_make_ui + local + one: INTEGER_X + do + create one.make_from_natural (0xffffffff) + assert ("{INTEGER_X}.make_ui", one.to_natural_32 = 0xffffffff) + end + + test_as_natural + local + one: INTEGER_X + do + create one.make_from_natural (0xffffffff) + assert ("{INTEGER_X}.as_natural", one.to_natural_32 = 0xffffffff) + end + + test_make_si + local + one: INTEGER_X + do + create one.make_from_integer (0x7fffffff) + assert ("{INTEGER_X}.make_si", one.to_integer_32 = 0x7fffffff) + end + + test_as_integer + local + one: INTEGER_X + do + create one.make_from_integer (0x7fffffff) + assert ("{INTEGER_X}.as_integer", one.to_integer_32 = 0x7fffffff) + end + + test_fits_natural_8_1 + local + one: INTEGER_X + int: NATURAL_8 + do + create one.make_from_string (int.max_value.out) + assert ("test fits natural 8 1", one.fits_natural_8) + end + + test_fits_natural_8_2 + local + one: INTEGER_X + int: NATURAL_8 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits natural 8 2", not one.fits_natural_8) + end + + test_fits_natural_8_3 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits natural 8 3", one.fits_natural_8) + end + + test_fits_natural_8_4 + local + one: INTEGER_X + do + create one.make_from_integer (-1) + assert ("test fits natural 8 4", not one.fits_natural_8) + end + + test_fits_natural_16_1 + local + one: INTEGER_X + int: NATURAL_16 + do + create one.make_from_string (int.max_value.out) + assert ("test fits natural 16 1", one.fits_natural_16) + end + + test_fits_natural_16_2 + local + one: INTEGER_X + int: NATURAL_16 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits natural 16 2", not one.fits_natural_16) + end + + test_fits_natural_16_3 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits natural 16 3", one.fits_natural_16) + end + + test_fits_natural_16_4 + local + one: INTEGER_X + do + create one.make_from_integer (-1) + assert ("test fits natural 16 4", not one.fits_natural_16) + end + + test_fits_natural_32_1 + local + one: INTEGER_X + int: NATURAL_32 + do + create one.make_from_string (int.max_value.out) + assert ("test fits natural 32 1", one.fits_natural_32) + end + + test_fits_natural_32_2 + local + one: INTEGER_X + int: NATURAL_32 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits natural 32 2", not one.fits_natural_32) + end + + test_fits_natural_32_3 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits natural 32 3", one.fits_natural_32) + end + + test_fits_natural_32_4 + local + one: INTEGER_X + do + create one.make_from_integer (-1) + assert ("test fits natural 32 4", not one.fits_natural_32) + end + + test_fits_natural_64_1 + local + one: INTEGER_X + int: NATURAL_64 + do + create one.make_from_string (int.max_value.out) + assert ("test fits natural 64 1", one.fits_natural_64) + end + + test_fits_natural_64_2 + local + one: INTEGER_X + int: NATURAL_64 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits natural 64 2", not one.fits_natural_64) + end + + test_fits_natural_64_3 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits natural 64 3", one.fits_natural_64) + end + + test_fits_natural_64_4 + local + one: INTEGER_X + do + create one.make_from_integer (-1) + assert ("test fits natural 64 4", not one.fits_natural_64) + end + + test_fits_integer_8_1 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.max_value.out) + assert ("test fits integer 8 1", one.fits_integer_8) + end + + test_fits_integer_8_2 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.min_value.out) + assert ("test fits integer 8 2", one.fits_integer_8) + end + + test_fits_integer_8_3 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits integer 8 3", not one.fits_integer_8) + end + + test_fits_integer_8_4 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test fits integer 8 4", not one.fits_integer_8) + end + + test_fits_integer_8_5 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits integer 8 5", one.fits_integer_8) + end + + test_fits_integer_16_1 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.max_value.out) + assert ("test fits integer 16 1", one.fits_integer_16) + end + + test_fits_integer_16_2 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.min_value.out) + assert ("test fits integer 16 2", one.fits_integer_16) + end + + test_fits_integer_16_3 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits integer 16 3", not one.fits_integer_16) + end + + test_fits_integer_16_4 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test fits integer 16 4", not one.fits_integer_16) + end + + test_fits_integer_16_5 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits integer 16 5", one.fits_integer_16) + end + + test_fits_integer_32_1 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.max_value.out) + assert ("test fits integer 32 1", one.fits_integer_32) + end + + test_fits_integer_32_2 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.min_value.out) + assert ("test fits integer 32 2", one.fits_integer_32) + end + + test_fits_integer_32_3 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits integer 32 3", not one.fits_integer_32) + end + + test_fits_integer_32_4 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test fits integer 32 4", not one.fits_integer_32) + end + + test_fits_integer_32_5 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits integer 32 5", one.fits_integer_32) + end + + test_fits_integer_64_1 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.max_value.out) + assert ("test fits integer 64 1", one.fits_integer_64) + end + + test_fits_integer_64_2 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.min_value.out) + assert ("test fits integer 64 2", one.fits_integer_64) + end + + test_fits_integer_64_3 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test fits integer 64 3", not one.fits_integer_64) + end + + test_fits_integer_64_4 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test fits integer 64 4", not one.fits_integer_64) + end + + test_fits_integer_64_5 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.max_value.out) + assert ("test fits integer 64 5", one.fits_integer_64) + end + + test_fits_integer_64_6 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.min_value.out) + assert ("test fits integer 64 6", one.fits_integer_64) + end + + test_fits_integer_64_7 + local + one: INTEGER_X + do + create one.make_from_integer (0) + assert ("test fits integer 64 7", one.fits_integer_64) + end + + test_swap + local + one: INTEGER_X + two: INTEGER_X + do + create one.make_from_integer (1) + create two.make_from_integer (2) + swap (one, two) + assert ("{INTEGER_X}.swap 1", two.to_integer_32 = 1) + assert ("{INTEGER_X}.swap 2", one.to_integer_32 = 2) + end + + test_init_set + local + one: INTEGER_X + two: INTEGER_X + do + create one.make_from_string ("0982430984230470238742037402394230948") + create two.make_set (one) + assert ("{INTEGER_X}.init_set", one ~ two) + end + + test_sub + -- Test integer subtraction cases, ++ +- -+ --, 0 sum + local + posone: INTEGER_X + postwo: INTEGER_X + negone: INTEGER_X + negtwo: INTEGER_X + ans: INTEGER_X + do + create posone.make_from_integer (1000) + create postwo.make_from_integer (2000) + create negone.make_from_integer (-1000) + create negtwo.make_from_integer (-2000) + ans := posone - postwo + assert ("{INTEGER_X}.sub test", ans.to_integer_32 = 1000 - 2000) + ans := postwo - negone + assert ("{INTEGER_X}.sub test", ans.to_integer_32 = 2000 - -1000) + ans := negone - postwo + assert ("{INTEGER_X}.sub test", ans.to_integer_32 = -1000 - 2000) + ans := negone - negtwo + assert ("{INTEGER_X}.sub test", ans.to_integer_32 = -1000 - -2000) + ans := posone - posone + assert ("{INTEGER_X}.sub test", ans.to_integer_32 = 1000 - 1000) + end + + test_negative + local + one: INTEGER_X + two: INTEGER_X + do + create one.make_from_integer (1) + create two.make_from_integer (-1) + assert ("test negative", one ~ two or one ~ -two) + end + + test_mul + -- Test multiplication cases, +- -+ + local + posone: INTEGER_X + negone: INTEGER_X + ans: INTEGER_X + do + create posone.make_from_integer (1000) + create negone.make_from_integer (-1000) + ans := posone * posone + assert ("{INTEGER_X}.mul test", ans.to_integer_32 = 1000 * 1000) + ans := posone * negone + assert ("{INTEGER_X}.mul test", ans.to_integer_32 = 1000 * -1000) + end + + test_div + -- Test integer division cases, pp, ppr, np, npr, nn, nnr + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + four: INTEGER_X + quot: INTEGER_X + do + create one.make_from_integer (42) + create two.make_from_integer (2) + create three.make_from_integer (-42) + create four.make_from_integer (-2) + quot := one / two + assert ("{INTEGER_X}.div test", quot.to_integer_32 = 42 // 2) + quot := two / one + assert ("{INTEGER_X}.div test", quot.to_integer_32 = 2 // 42) + quot := three / two + assert ("{INTEGER_X}.div test", quot.to_integer_32 = -42 // 2) + quot := two / three + assert ("{INTEGER_X}.div test", quot.to_integer_32 = 2 // -42) + quot := three / four + assert ("{INTEGER_X}.div test", quot.to_integer_32 = -42 // -2) + quot := four / three + assert ("{INTEGER_X}.div test", quot.to_integer_32 = -2 // -42) + end + + test_abs + -- Test absolute value cases + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + ans: INTEGER_X + do + create one.make_from_integer (1) + create two.make_from_integer (-1) + create three.make_from_integer (0) + ans := one.abs_value + assert ("INTEGER_X.abs positive", ans.to_integer_32 = 1) + ans := two.abs_value + assert ("INTEGER_X.abs negative", ans.to_integer_32 = 1) + ans := three.abs_value + assert ("INTEGER_X.abs zero", ans.to_integer_32 = 0) + end + + test_comp + -- Test comparison function cases + local + one: INTEGER_X + two: INTEGER_X + three:INTEGER_X + do + create one.make_from_integer (1000) + create two.make_from_integer (2000) + create three.make_from_integer (1000) + + assert ("INTEGER_X.comp eq", one.is_equal (three) = TRUE) + assert ("INTEGER_X.comp lt", one.is_less (two) = TRUE) + assert ("INTEGER_X.comp lt", two.is_less (one) = FALSE) + assert ("INTEGER_X.comp le", one.is_less_equal (two) = TRUE) + assert ("INTEGER_X.comp le", one.is_less_equal (three) = TRUE) + assert ("INTEGER_X.comp le", two.is_less_equal (one) = FALSE) + assert ("INTEGER_X.comp gt", one.is_greater (two) = FALSE) + assert ("INTEGER_X.comp gt", two.is_greater (one) = TRUE) + assert ("INTEGER_X.comp ge", one.is_greater_equal (two) = FALSE) + assert ("INTEGER_X.comp ge", one.is_greater_equal (three) = TRUE) + assert ("INTEGER_X.comp ge", two.is_greater_equal (one) = TRUE) + + end + + + +end + + diff --git a/library/crypto/eapml/tests/test_integer_x_access.e b/library/crypto/eapml/tests/test_integer_x_access.e new file mode 100644 index 00000000..c0f7b35b --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_access.e @@ -0,0 +1,395 @@ +note + description: "Summary description for {TEST_INTEGER_X_ACCESS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_ACCESS + +inherit + EQA_TEST_SET + INTEGER_X_ACCESS + undefine + default_create + end + +feature + test_get_integer_64_1 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.max_value.out) + assert ("test get integer 64 1 1", one.fits_integer_64) + assert ("test get integer 64 1 2", one.as_integer_64 = int.max_value) + end + + test_get_integer_64_2 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.min_value.out) + assert ("test get integer 64 2 1", one.fits_integer_64) + assert ("test get integer 64 2 2", one.as_integer_64 = int.min_value) + end + + test_get_integer_64_3 + local + one: INTEGER_X + do + create one.make_from_string ("0") + assert ("test get integer 64 3 1", one.fits_integer_64) + assert ("test get integer 64 3 2", one.as_integer_64 = 0) + end + + test_get_integer_64_4 + local + one: INTEGER_X + do + create one.make_from_string ("-1") + assert ("test get integer 64 4 1", one.fits_integer_64) + assert ("test get integer 64 4 2", one.as_integer_64 = -1) + end + + test_get_integer_64_5 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test get integer 64 5 1", not one.fits_integer_64) + assert ("test get integer 64 5 2", one.as_integer_64 = 0) + end + + test_get_integer_64_6 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test get integer 64 6 1", not one.fits_integer_64) + assert ("test get integer 64 6 2", one.as_integer_64 = -1) + end + + test_get_integer_32_1 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.max_value.out) + assert ("test get integer 32 1 1", one.fits_integer_32) + assert ("test get integer 32 1 2", one.as_integer_32 = int.max_value) + end + + test_get_integer_32_2 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.min_value.out) + assert ("test get integer 32 2 1", one.fits_integer_32) + assert ("test get integer 32 2 2", one.as_integer_32 = int.min_value) + end + + test_get_integer_32_3 + local + one: INTEGER_X + do + create one.make_from_string ("0") + assert ("test get integer 32 3 1", one.fits_integer_32) + assert ("test get integer 32 3 2", one.as_integer_32 = 0) + end + + test_get_integer_32_4 + local + one: INTEGER_X + do + create one.make_from_string ("-1") + assert ("test get integer 32 4 1", one.fits_integer_32) + assert ("test get integer 32 4 2", one.as_integer_32 = -1) + end + + test_get_integer_32_5 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test get integer 32 5 1", not one.fits_integer_32) + assert ("test get integer 32 5 2", one.as_integer_32 = 0) + end + + test_get_integer_32_6 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test get integer 32 6 1", not one.fits_integer_32) + assert ("test get integer 32 6 2", one.as_integer_32 = -1) + end + + test_get_integer_16_1 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.max_value.out) + assert ("test get integer 16 1 1", one.fits_integer_16) + assert ("test get integer 16 1 2", one.as_integer_16 = int.max_value) + end + + test_get_integer_16_2 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.min_value.out) + assert ("test get integer 16 2 1", one.fits_integer_16) + assert ("test get integer 16 2 2", one.as_integer_16 = int.min_value) + end + + test_get_integer_16_3 + local + one: INTEGER_X + do + create one.make_from_string ("0") + assert ("test get integer 16 3 1", one.fits_integer_16) + assert ("test get integer 16 3 2", one.as_integer_16 = 0) + end + + test_get_integer_16_4 + local + one: INTEGER_X + do + create one.make_from_string ("-1") + assert ("test get integer 16 4 1", one.fits_integer_16) + assert ("test get integer 16 4 2", one.as_integer_16 = -1) + end + + test_get_integer_16_5 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test get integer 16 5 1", not one.fits_integer_16) + assert ("test get integer 16 5 2", one.as_integer_16 = 0) + end + + test_get_integer_16_6 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test get integer 16 6 1", not one.fits_integer_16) + assert ("test get integer 16 6 2", one.as_integer_16 = -1) + end + + test_get_integer_8_1 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.max_value.out) + assert ("test get integer 8 1 1", one.fits_integer_8) + assert ("test get integer 8 1 2", one.as_integer_8 = int.max_value) + end + + test_get_integer_8_2 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.min_value.out) + assert ("test get integer 8 2 1", one.fits_integer_8) + assert ("test get integer 8 2 2", one.as_integer_8 = int.min_value) + end + + test_get_integer_8_3 + local + one: INTEGER_X + do + create one.make_from_string ("0") + assert ("test get integer 8 3 1", one.fits_integer_8) + assert ("test get integer 8 3 2", one.as_integer_8 = 0) + end + + test_get_integer_8_4 + local + one: INTEGER_X + do + create one.make_from_string ("-1") + assert ("test get integer 8 4 1", one.fits_integer_8) + assert ("test get integer 8 4 2", one.as_integer_8 = -1) + end + + test_get_integer_8_5 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.max_value.out) + one.plus (one.one) + assert ("test get integer 8 5 1", not one.fits_integer_8) + assert ("test get integer 8 5 2", one.as_integer_8 = 0) + end + + test_get_integer_8_6 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_string (int.min_value.out) + one.minus (one.one) + assert ("test get integer 8 6 1", not one.fits_integer_8) + assert ("test get integer 8 6 2", one.as_integer_8 = -1) + end + + test_get_str_1 + local + one: INTEGER_X + output: STRING + do + create one.make_limbs (4) + one.item [0] := 0x87654321 + one.item [1] := 0xcccccccc + one.item [2] := 0x33333333 + one.item [3] := 0xffffffff + one.count := 4 + output := one.out_base (16) + assert ("test get str 1", "ffffffff33333333cccccccc87654321" ~ output) + end + + test_get_str_2 + local + one: INTEGER_X + output: STRING + do + create one.make_limbs (4) + one.item [0] := 0x87654321 + one.item [1] := 0xcccccccc + one.item [2] := 0x33333333 + one.item [3] := 0xffffffff + one.count := 4 + output := one.out_base (10) + assert ("test get str 2", "340282366857555933463031183799994368801" ~ output) + end + + test_get_str_3 + local + one: INTEGER_X + two: INTEGER_X + output: STRING + i: INTEGER + base: INTEGER + do + from + i := 0 + until + i > 1000 + loop + base := i \\ 61 + 2 + create one.make_random (256) + output := one.out_base (base) + create two.make_from_string_base (output, base) + assert ("test get str 3", one ~ two) + i := i + 1 + end + end + + test_get_str_4 + local + one: INTEGER_X + output: STRING + do + create one.make_limbs (8) + one.item [0] := 0x99811941 + one.item [1] := 0x841FD605 + one.item [2] := 0xD960A1BF + one.item [3] := 0x5E433EFC + one.item [4] := 0x48C9BC93 + one.item [5] := 0x1C8B6FB1 + one.item [6] := 0x8CA06DE0 + one.item [7] := 0xC6182337 + one.count := 8 + output := one.out_base (10) + assert ("test get str 4", output ~ "89600591407770348063754312463218194105764385355557091513583682190076098451777") + end + + test_get_str_5 + local + one: INTEGER_X + output: STRING + do + create one.make_limbs (8) + one.item [0] := 0x99811941 + one.item [1] := 0x841FD605 + one.item [2] := 0xD960A1BF + one.item [3] := 0x5E433EFC + one.item [4] := 0x48C9BC93 + one.item [5] := 0x1C8B6FB1 + one.item [6] := 0x8CA06DE0 + one.item [7] := 0xC6182337 + one.count := 8 + output := one.out_base (3) + assert ("test get str 5", output ~ "110022012022022000201210111012211020111202020222100010210022020220110011011010201011020001011210101000122212110112010121211022120122101102102020102011202010010112") + end + + test_get_str_6 + local + one: INTEGER_X + output: STRING + do + create one.make_limbs (8) + one.item [7] := 0x8134b7f7 + one.item [6] := 0x8d570cbf + one.item [5] := 0xeb5f7c66 + one.item [4] := 0x7aa64334 + one.item [3] := 0xbb6cd783 + one.item [2] := 0x22792988 + one.item [1] := 0x6ec0f7ac + one.item [0] := 0x4438ad87 + one.count := 8 + output := one.out_base (7) + assert ("test get str 6", output ~ "5050422450443414252030234161450453214063666050554216601312032162510626626621233550541413260") + end + + test_get_str_7 + local + one: INTEGER_X + output: STRING + do + create one.make_limbs (8) + one.item [0] := 0x8134b7f7 + one.item [1] := 0x8d570cbf + one.item [2] := 0xeb5f7c66 + one.item [3] := 0x7aa64334 + one.item [4] := 0xbb6cd783 + one.item [5] := 0x22792988 + one.item [6] := 0x6ec0f7ac + one.item [7] := 0x4438ad87 + one.count := 8 + output := one.out_base (7) + assert ("test get str 7", output ~ "2460223246331335544520513341363224654146046636101125253015521231163466226621435340120452343") + end + + test_get_str_8 + local + one: INTEGER_X + output: STRING + do + create one.make_from_integer (-1) + output := one.out_hex + assert ("test get str 7", output ~ "-1") + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_arithmetic.e b/library/crypto/eapml/tests/test_integer_x_arithmetic.e new file mode 100644 index 00000000..2567fdb5 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_arithmetic.e @@ -0,0 +1,208 @@ +note + description: "Summary description for {TEST_INTEGER_ARITHMETIC}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_ARITHMETIC + +inherit + EQA_TEST_SET + INTEGER_X_ARITHMETIC + undefine + default_create + end + +feature + test_add_1 + -- Test integer addition cases, ++ +- -+ --, 0 sum + local + posone: INTEGER_X + postwo: INTEGER_X + negone: INTEGER_X + negtwo: INTEGER_X + ans: INTEGER_X + do + create posone.make_from_integer (1000) + create postwo.make_from_integer (2000) + create negone.make_from_integer (-1000) + create negtwo.make_from_integer (-2000) + ans := posone + postwo + assert ("{INTEGER_X}.add test", ans.to_integer_32 = 1000 + 2000) + ans := postwo + negone + assert ("{INTEGER_X}.add test", ans.to_integer_32 = 2000 + -1000) + ans := negone + postwo + assert ("{INTEGER_X}.add test", ans.to_integer_32 = -1000 + 2000) + ans := negone + negtwo + assert ("{INTEGER_X}.add test", ans.to_integer_32 = -1000 + -2000) + ans := posone + negone + assert ("{INTEGER_X}.add test", ans.to_integer_32 = 1000 + -1000) + end + + test_add_2 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one.make_limbs (6) + create two.make_from_hex_string ("343bd97a 7e17702a 800c8f10 54ad58f6 1f07c505") + create three.make_from_hex_string ("ffffffff ffffffff ffffffff ffffffff 7ffffffc") + create expected.make_from_hex_string ("1343bd97a7e17702a800c8f1054ad58f59f07c501") + add (one, two, three) + assert ("test add 2", one ~ expected) + end + + test_add_3 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("a9993e364706816aba3e25717850c26c9cd0d89d") + create three.make_from_hex_string ("8913681113524c02ac9b2b8777f53c1feb356bfbc122bf1970d1ccc8fc43f9bb8aec1812ee98e4a2") + create expected.make_from_hex_string ("8913681113524c02ac9b2b8777f53c1feb356bfc6abbfd4fb7d84e33b6821f2d033cda7f8b69bd3f") + add (one, two, three) + assert ("test add 3", one ~ expected) + end + + test_add_4 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("-7231ea35689f4fd7ce163d502a7e14c99947e909fb2a9d7cad460fb337fae053af6e5a5419a6800c19f28b09a3a1f005621dd631b6d93fcc32e4e6069e76fb15") + create three.make_from_hex_string ("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + create expected.make_from_hex_string ("1ff8dce15ca9760b02831e9c2afd581eb3666b816f604d5628352b9f04cc8051fac5091a5abe6597ff3e60d74f65c5e0ffa9de229ce4926c033cd1b19f9618904ea") + add (one, two, three) + assert ("test add 4", one ~ expected) + end + + test_sub_1 + local + one_three: INTEGER_X + two: INTEGER_X + expected: INTEGER_X + do + create one_three.make_from_hex_string ("014fae42 56ad0915 2a7b2b66 fe887b52 e06ffa35 d359cd33 14156137 564096ef 90eb9c01 9ee82ea9") + create two.make_from_hex_string ("1") + create expected.make_from_hex_string ("-014fae42 56ad0915 2a7b2b66 fe887b52 e06ffa35 d359cd33 14156137 564096ef 90eb9c01 9ee82ea8") + sub (one_three, two, one_three) + assert ("test sub 1", one_three ~ expected) + end + + test_sub_2 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("1429cb78799228669deb4a9025f308ab78be74ae") + create three.make_from_hex_string ("-f7c5cdcb7d66c16bbf17e81de30488c02078684") + create expected.make_from_hex_string ("23a628553168947d59dcc912042351377ac5fb32") + sub (one, two, three) + assert ("test sub 2", one ~ expected) + end + + test_mul_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one.make_limbs (10) + create two.make_limbs (5) + create three.make_limbs (6) + create expected.make_from_hex_string ("30f2de49 bab11556 78be37e5 d4205117 663c6cc5 5fd1e2bd 41b4a8fd 35ce30b2 07939fb8 c29af9f6") + two.item [0] := 0x9f07c4ff + two.item [1] := 0xd4ad58f1 + two.item [2] := 0x800c8f0e + two.item [3] := 0x7e17702a + two.item [4] := 0x343bd97a + two.count := 5 + three.item [0] := 0xfb4ab80a + three.item [1] := 0x2077ac6a + three.item [2] := 0x5bdd4431 + three.item [3] := 0x6672da8e + three.item [4] := 0xefe650c5 + three.count := 5 + mul (one, two, three) + assert ("test mul 1", expected ~ one) + end + + test_mul_2 + local + one_three: INTEGER_X + two: INTEGER_X + expected: INTEGER_X + do + create one_three.make_limbs (6) + create two.make_limbs (5) + create expected.make_from_hex_string ("30f2de49 bab11556 78be37e5 d4205117 663c6cc5 5fd1e2bd 41b4a8fd 35ce30b2 07939fb8 c29af9f6") + two.item [0] := 0x9f07c4ff + two.item [1] := 0xd4ad58f1 + two.item [2] := 0x800c8f0e + two.item [3] := 0x7e17702a + two.item [4] := 0x343bd97a + two.count := 5 + one_three.item [0] := 0xfb4ab80a + one_three.item [1] := 0x2077ac6a + one_three.item [2] := 0x5bdd4431 + one_three.item [3] := 0x6672da8e + one_three.item [4] := 0xefe650c5 + one_three.count := 5 + mul (one_three, two, one_three) + assert ("test mul 1", expected ~ one_three) + end + + test_mul_3 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("-e69e4c55 8d0e2ed0 10128582 48b54fe8 8e87802e c871b791 5347fc54 8fb749de 9bc6e6b7 1868a715 859bcde6 96d6f196 37ad0367 26bc4cea 65f0d20e 67321392") + create three.make_from_hex_string ("000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff") + create expected.make_from_hex_string ("-1cd3c98ab1a1c5da020250b04916a9fd11d0f005d90e36f22a68ff8a91f6e93bd378dcd6e30d14e2b0b379bcd2dade32c6f5a06ce4d7899d4cbe1a41cce642723ff1961b3aa72f1d12fefed7a7db74ab01771787fd1378e486eacb803ab7048b62164391948e79758ea7a64321969290e69c852fc98d943b3159a0f2df198cdec6e") + mul (one, two, three) + assert ("test mul 3", one ~ expected) + end + + test_mul_2exp_1 + local + one: INTEGER_X + two: INTEGER_X + expected: INTEGER_X + do + create one.make_limbs (7) + create two.make_from_hex_string ("2 fe13c053 7bbc11ac aa07d793 de4e6d5e 5c94eee8") + create expected.make_from_hex_string ("0000000b f84f014d eef046b2 a81f5e4f 7939b579 7253bba0") + mul_2exp (one, two, 2) + assert ("test mul 2exp 1", one ~ expected) + end + + test_mul_2exp_2 + local + one: INTEGER_X + two: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("8 00000000 00000000 00000000 00000000 00000000") + create expected.make_from_hex_string ("8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + mul_2exp (one, two, 0x80) + assert ("test mul 2exp 2", one ~ expected) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_assignment.e b/library/crypto/eapml/tests/test_integer_x_assignment.e new file mode 100644 index 00000000..44538020 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_assignment.e @@ -0,0 +1,217 @@ +note + description: "Summary description for {TEST_INTEGER_X_ASSIGNMENT}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_ASSIGNMENT + +inherit + EQA_TEST_SET + INTEGER_X_ASSIGNMENT + undefine + default_create + end + +feature + test_set_str_1 + local + target: INTEGER_X + do + create target + set_str (target, "100", 10) + assert ("test set str 1 1", target.item [0] = 100 and target.count = 1) + + set_str (target, "10000000000", 10) + assert ("test set str 1 2", target.item [0] = 0x540be400 and target.item [1] = 0x00000002 and target.count = 2) + end + + test_set_str_2 + local + target: INTEGER_X + do + create target + set_str (target, "1000", 16) + assert ("test set str 1 1", target.item [0] = 0x1000 and target.count = 1) + + set_str (target, "100000000000", 16) + assert ("test set str 1 2", target.item [0] = 0x00000000 and target.item [1] = 0x00001000 and target.count = 2) + end + + test_set_str_3 + local + target: INTEGER_X + do + create target + set_str (target, " 1 0 0 0 ", 16) + assert ("test set str 3 1", target.item [0] = 0x1000 and target.count = 1) + set_str (target, " 1 0 0 0 0 0 0 0 0 0 0 0 ", 16) + assert ("test set str 3 2", target.item [0] = 0x00000000 and target.item [1] = 0x00001000 and target.count = 2) + end + + test_set_str_4 + local + target: INTEGER_X + do + create target + set_str (target, " 0x 1 0 0 0 ", 0) + assert ("test set str 3 1", target.item [0] = 0x1000 and target.count = 1) + set_str (target, " 0", 0) + assert ("test set str 3 2", target.count = 0) + end + + test_set_str_5 + local + one: INTEGER_X + do + create one.make_from_string_base ("5050422450443414252030234161450453214063666050554216601312032162510626626621233550541413260", 7) + assert ("test set str 5", one.item [7] = 0x8134b7f7 and one.item [6] = 0x8d570cbf and one.item [5] = 0xeb5f7c66 and one.item [4] = 0x7aa64334 and one.item [3] = 0xbb6cd783 and one.item [2] = 0x22792988 and one.item [1] = 0x6ec0f7ac and one.item [0] = 0x4438ad87 and one.count = 8) + end + + test_set_str_6 + local + one: INTEGER_X + do + create one.make_from_string_base ("2460223246331335544520513341363224654146046636101125253015521231163466226621435340120452343", 7) + assert ("test set str 6", one.item [0] = 0x8134b7f7 and one.item [1] = 0x8d570cbf and one.item [2] = 0xeb5f7c66 and one.item [3] = 0x7aa64334 and one.item [4] = 0xbb6cd783 and one.item [5] = 0x22792988 and one.item [6] = 0x6ec0f7ac and one.item [7] = 0x4438ad87 and one.count = 8) + end + + test_set_str_7 + local + one: INTEGER_X + do + create one.make_from_hex_string ("1") + assert ("test set str 7", one.item [0] = 0x1 and one.count = 1) + end + + test_set_1 + local + one: INTEGER_X + two: INTEGER_X + do + create one.make_from_hex_string ("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") + assert ("test set 1 1", one.item [0] = 0xfcfdfeff and one.item [1] = 0xf8f9fafb and one.item [2] = 0xf4f5f6f7 and one.item [3] = 0xf0f1f2f3 and one.count = 4) + create two + two.copy (one) + assert ("test set 1 2", one ~ two) + assert ("test set 1 3", one.item [0] = 0xfcfdfeff and one.item [1] = 0xf8f9fafb and one.item [2] = 0xf4f5f6f7 and one.item [3] = 0xf0f1f2f3 and one.count = 4) + assert ("test set 1 4", two.item [0] = 0xfcfdfeff and two.item [1] = 0xf8f9fafb and two.item [2] = 0xf4f5f6f7 and two.item [3] = 0xf0f1f2f3 and two.count = 4) + end + + test_set_from_integer_64_1 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_integer_64 (int.min_value) + assert ("test set from integer 64 1 1", one.fits_integer_64) + assert ("test set from integer 64 1 2", one.to_integer_64 = int.min_value) + end + + test_set_from_integer_64_2 + local + one: INTEGER_X + do + create one.make_from_integer_64 (-1) + assert ("test set from integer 64 2 1", one.fits_integer_64) + assert ("test set from integer 64 2 2", one.to_integer_64 = -1) + end + + test_set_from_integer_64_3 + local + one: INTEGER_X + int: INTEGER_64 + do + create one.make_from_integer_64 (int.max_value) + assert ("test set from integer 64 3 1", one.fits_integer_64) + assert ("test set from integer 64 3 2", one.to_integer_64 = int.max_value) + end + + test_set_from_integer_32_1 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_integer_32 (int.min_value) + assert ("test set from integer 32 1 1", one.fits_integer_32) + assert ("test set from integer 32 1 2", one.to_integer_32 = int.min_value) + end + + test_set_from_integer_32_2 + local + one: INTEGER_X + do + create one.make_from_integer_32 (-1) + assert ("test set from integer 32 2 1", one.fits_integer_32) + assert ("test set from integer 32 2 2", one.to_integer_32 = -1) + end + + test_set_from_integer_32_3 + local + one: INTEGER_X + int: INTEGER_32 + do + create one.make_from_integer_32 (int.max_value) + assert ("test set from integer 32 3 1", one.fits_integer_32) + assert ("test set from integer 32 3 2", one.to_integer_32 = int.max_value) + end + + test_set_from_integer_16_1 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_integer_16 (int.min_value) + assert ("test set from integer 16 1 1", one.fits_integer_16) + assert ("test set from integer 16 1 2", one.to_integer_16 = int.min_value) + end + + test_set_from_integer_16_2 + local + one: INTEGER_X + do + create one.make_from_integer_16 (-1) + assert ("test set from integer 16 2 1", one.fits_integer_16) + assert ("test set from integer 16 2 2", one.to_integer_16 = -1) + end + + test_set_from_integer_16_3 + local + one: INTEGER_X + int: INTEGER_16 + do + create one.make_from_integer_16 (int.max_value) + assert ("test set from integer 16 3 1", one.fits_integer_16) + assert ("test set from integer 16 3 2", one.to_integer_16 = int.max_value) + end + + test_set_from_integer_8_1 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_integer_8 (int.min_value) + assert ("test set from integer 8 1 1", one.fits_integer_8) + assert ("test set from integer 8 1 2", one.to_integer_8 = int.min_value) + end + + test_set_from_integer_8_2 + local + one: INTEGER_X + do + create one.make_from_integer_8 (-1) + assert ("test set from integer 8 2 1", one.fits_integer_8) + assert ("test set from integer 8 2 2", one.to_integer_8 = -1) + end + + test_set_from_integer_8_3 + local + one: INTEGER_X + int: INTEGER_8 + do + create one.make_from_integer_8 (int.max_value) + assert ("test set from integer 8 3 1", one.fits_integer_8) + assert ("test set from integer 8 3 2", one.to_integer_8 = int.max_value) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_division.e b/library/crypto/eapml/tests/test_integer_x_division.e new file mode 100644 index 00000000..8ee46dfa --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_division.e @@ -0,0 +1,32 @@ +note + description: "Summary description for {INTEGER_X_DIVISION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_DIVISION + +inherit + EQA_TEST_SET + INTEGER_X_DIVISION + undefine + default_create + end + +feature + test_tdiv_q_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("-014fae42 56ad0915 2a7b2b66 fe887b52 e06ffa35 d359cd33 14156137 564096ef 90eb9c01 9ee82ea9") + create three.make_from_hex_string ("474c50aa 62d128fa b3b99224 0846a26e f58bf664") + create expected.make_from_hex_string ("-04b547f5 df885395 a422bbce 998d2570 9019af3a") + tdiv_q (one, two, three) + assert ("test tdiv q 1", one ~ expected) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_gcd.e b/library/crypto/eapml/tests/test_integer_x_gcd.e new file mode 100644 index 00000000..a7f79002 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_gcd.e @@ -0,0 +1,92 @@ +note + description: "Summary description for {TEST_INTEGER_X_GCD}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_GCD + +inherit + EQA_TEST_SET + INTEGER_X_GCD + undefine + default_create + end + +feature + test_gcd_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("75bd a09fab66 22ddfba5 6141c975") + create three.make_from_hex_string ("db7c 2abf62e3 5e668076 bead208b") + create expected.make_from_integer (1) + gcd (one, two, three) + assert ("test gcd 1", one ~ expected) + end + + test_gcd_2 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("1f3e 0565ad11 0943df37 0be1f345") + create three.make_from_hex_string ("db7c 2abf62e3 5e668076 bead208b") + create expected.make_from_integer (1) + gcd (one, two, three) + assert ("test gcd 2", one ~ expected) + end + + test_gcd_3 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("b900 97df5038 7e2f36a6 2ed3a8f4") + create three.make_from_hex_string ("db7c 2abf62e3 5e668076 bead208b") + create expected.make_from_integer (1) + gcd (one, two, three) + assert ("test gcd 3", one ~ expected) + end + + test_gcd_4 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("905a 1c3f4cec 73b96934 ac732c70") + create three.make_from_hex_string ("db7c 2abf62e3 5e668076 bead208b") + create expected.make_from_integer (1) + gcd (one, two, three) + assert ("test gcd 4", one ~ expected) + end + + test_gcd_5 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("1ffb369d437c5d32145fd9a1223ab960e362ffd5545b675f7ead44be35a12c61699c05dd8ecafb643b9feb6912fb6df6c57eca1c0e4ff132ed5d77d6bb5d96a4395") + create three.make_from_hex_string ("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + create expected.make_from_hex_string ("1") + gcd (one, two, three) + assert ("test gcd 5", one ~ expected) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_io.e b/library/crypto/eapml/tests/test_integer_x_io.e new file mode 100644 index 00000000..ea4cb702 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_io.e @@ -0,0 +1,89 @@ +note + description: "Summary description for {TEST_INTEGER_X_IO}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_IO + +inherit + EQA_TEST_SET + INTEGER_X_IO + undefine + default_create + end + +feature + test_export_1 + local + one: INTEGER_X + two: SPECIAL [NATURAL_8] + junk: TUPLE [junk: INTEGER] + do + create junk + create one.make_limbs (6) + one.item [0] := 0x7393172a + one.item [1] := 0xe93d7e11 + one.item [2] := 0x2e409f96 + one.item [3] := 0x6bc1bee2 + one.count := 4 + create two.make_filled (0, 16) + output (two, 0, junk, 1, 1, -1, one) + assert ("test output 1 1", two [0] = 0x6b and two [1] = 0xc1 and two [2] = 0xbe and two [3] = 0xe2) + assert ("test output 1 2", two [4] = 0x2e and two [5] = 0x40 and two [6] = 0x9f and two [7] = 0x96) + assert ("test output 1 3", two [8] = 0xe9 and two [9] = 0x3d and two [10] = 0x7e and two [11] = 0x11) + assert ("test output 1 4", two [12] = 0x73 and two [13] = 0x93 and two [14] = 0x17 and two [15] = 0x2a) + end + + test_import_1 + local + one: INTEGER_X + two: SPECIAL [NATURAL_8] + do + create two.make_filled (0, 16) + two [0] := 0x6b two [1] := 0xc1 two [2] := 0xbe two [3] := 0xe2 + two [4] := 0x2e two [5] := 0x40 two [6] := 0x9f two [7] := 0x96 + two [8] := 0xe9 two [9] := 0x3d two [10] := 0x7e two [11] := 0x11 + two [12] := 0x73 two [13] := 0x93 two [14] := 0x17 two [15] := 0x2a + create one + input (one, 16, 1, 1, -1, two, 0) + assert ("test input 1", one.item [0] = 0x7393172a and one.item [1] = 0xe93d7e11 and one.item [2] = 0x2e409f96 and one.item [3] = 0x6bc1bee2) + end + + test_export_2 + local + one: INTEGER_X + two: SPECIAL [NATURAL_8] + junk: TUPLE [junk: INTEGER] + do + create junk + create one.make_limbs (6) + one.item [0] := 0x0c0d0e0f + one.item [1] := 0x08090a0b + one.item [2] := 0x04050607 + one.item [3] := 0x00010203 + one.count := 4 + create two.make_filled (0, 16) + output (two, 0, junk, 1, 1, -1, one) + assert ("test export 1 1", two [0] = 0x01 and two [1] = 0x02 and two [2] = 0x03 and two [3] = 0x04) + assert ("test export 1 2", two [4] = 0x05 and two [5] = 0x06 and two [6] = 0x07 and two [7] = 0x08) + assert ("test export 1 3", two [8] = 0x09 and two [9] = 0x0a and two [10] = 0x0b and two [11] = 0x0c) + assert ("test export 1 4", two [12] = 0x0d and two [13] = 0x0e and two [14] = 0x0f and two [15] = 0x00) + end + + test_import_2 + local + one: INTEGER_X + two: SPECIAL [NATURAL_8] + do + create two.make_filled (0, 16) + two [0] := 0x01 two [1] := 0x02 two [2] := 0x03 two [3] := 0x04 + two [4] := 0x05 two [5] := 0x06 two [6] := 0x07 two [7] := 0x08 + two [8] := 0x09 two [9] := 0x0a two [10] := 0x0b two [11] := 0x0c + two [12] := 0x0d two [13] := 0x0e two [14] := 0x0f two [15] := 0x0 + create one + input (one, 16, 1, 1, -1, two, 0) + assert ("test import 2", one.item [0] = 0x0d0e0f00 and one.item [1] = 0x090a0b0c and one.item [2] = 0x05060708 and one.item [3] = 0x01020304) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_logic.e b/library/crypto/eapml/tests/test_integer_x_logic.e new file mode 100644 index 00000000..5ef02bac --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_logic.e @@ -0,0 +1,126 @@ +note + description: "Summary description for {TEST_INTEGER_X_LOGIC}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_LOGIC + +inherit + EQA_TEST_SET + INTEGER_X_LOGIC + undefine + default_create + end + +feature + + test_xor_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("7253bba0 7253bba0 7253bba0 7253bba0 7253bba0") + create three.make_from_hex_string ("5fc2780a 6f778235 9540faf2 7bc9cdab cb929ddd") + create expected.make_from_hex_string ("2d91c3aa 1d243995 e7134152 099a760b b9c1267d") + bit_xor (one, two, three) + assert ("test xor 1", one ~ expected) + end + + test_xor_lshift_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_hex_string ("7253bba0 7253bba0 7253bba0 7253bba0 7253bba0") + create three.make_from_hex_string ("5fc2780a 6f778235 9540faf2 7bc9cdab cb929ddd") + create expected.make_from_hex_string ("5fc2 780a6f77 f0662ee0 88a1c069 bff87032 ef8ebba0 7253bba0") + bit_xor_lshift (one, two, three, 48) + assert ("test xor lshift 1", one ~ expected) + end + + test_walking_xor_1 + local + i: INTEGER + ones: INTEGER_X + zero: INTEGER_X + cursor: INTEGER_X + xored: INTEGER_X + j: INTEGER + do + create zero + create ones.make_from_hex_string ("ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff") + from + i := 0 + until + i >= 256 + loop + cursor := zero.bit_complement_value (i) + xored := cursor.bit_xor_value (ones) + from + j := 0 + until + j >= 256 + loop + assert ("test walking xor 1 iteration: " + i.out, (j /= i) = xored.bit_test (j)) + j := j + 1 + end + i := i + 1 + end + end + + test_walking_set_bit_1 + local + i: INTEGER + j: INTEGER + zero: INTEGER_X + cursor: INTEGER_X + do + create zero.default_create + from + i := 0 + until + i >= 256 + loop + cursor := zero.set_bit_value (true, i) + from + j := 0 + until + j >= 256 + loop + assert ("test walking set bit 1 iteration: " + i.out, (j = i) = cursor.bit_test (j)) + j := j + 1 + end + i := i + 1 + end + end + + test_bit_clear_1 + local + one: INTEGER_X + expected: INTEGER_X + do + create one.make_from_hex_string ("c 7ea29e73 e8b0ed09 f2d91bac ab1cd267 343dfdb2") + create expected.make_from_hex_string ("4 7ea29e73 e8b0ed09 f2d91bac ab1cd267 343dfdb2") + bit_clear (one, 0xa3) + assert ("test bit clear 1", one ~ expected) + end + + test_bit_clear_2 + local + one: INTEGER_X + expected: INTEGER_X + do + create one.make_from_hex_string ("ece1f5243f82d99431001da4573c") + one.set_bit (False, 226) + create expected.make_from_hex_string ("ece1f5243f82d99431001da4573c") + assert ("test bit clear 2", one ~ expected) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_number_theory.e b/library/crypto/eapml/tests/test_integer_x_number_theory.e new file mode 100644 index 00000000..365c8574 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_number_theory.e @@ -0,0 +1,266 @@ +note + description: "Summary description for {TEST_INTEGER_X_NUMBER_THEORY}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_NUMBER_THEORY + +inherit + EQA_TEST_SET + INTEGER_X_NUMBER_THEORY + undefine + default_create + end + +feature + test_invert_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + has: BOOLEAN + do + create one + create two.make_from_hex_string ("474c50aa 62d128fa b3b99224 0846a26e f58bf664") + create three.make_from_hex_string ("ffffffff ffffffff ffffffff ffffffff 7fffffff") + create expected.make_from_hex_string ("fb4ab80a 2077ac6a 5bdd4431 6672da8e efe650c5") + has := invert (one, two, three) + assert ("test invert 1", has and one ~ expected) + end + + test_invert_2 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + has: BOOLEAN + do + create one + create two.make_from_hex_string ("51875f78 fcf4ae64 66099f92 3707f601") + create three.make_from_hex_string ("fffffffd ffffffff ffffffff ffffffff") + create expected.make_from_hex_string ("86043be0 479c80d7 d8181a73 7e4b676a") + has := invert (one, two, three) + assert ("test invert 2", has and one ~ expected) + end + + test_invert_3 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + has: BOOLEAN + do + create one + create two.make_from_hex_string ("4aa462dfb47b5da4294b5351ba91eaa46e808bc8052e951c4f2508a87b96ef400b15f688d8e16b449bf3247ffcddb250b39605a9c31de7167167504b440f14bc") + create three.make_from_hex_string ("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + create expected.make_from_hex_string ("1ff8dce15ca9760b02831e9c2afd581eb3666b816f604d5628352b9f04cc8051fac5091a5abe6597ff3e60d74f65c5e0ffa9de229ce4926c033cd1b19f9618904ea") + has := invert (one, two, three) + assert ("test invert 3", has and one ~ expected) + end + + test_invert_4 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + four: INTEGER_X + has: BOOLEAN + i: INTEGER + one_constant: INTEGER_X + do + create one + create three.make_from_string ("35742549198872617291353508656626642567") + create one_constant.make_from_integer (1) + from + i := 0 + until + i > 1000 + loop + create two.make_random_max (three) + has := invert (one, two, three) + four := one * two \\ three + assert ("test invert 4 iteration: " + i.out, has and four ~ one_constant) + i := i + 1 + end + end + + test_invert_5 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + expected: INTEGER_X + has: BOOLEAN + do + create one + create two.make_from_hex_string ("3a4085c123535aa7ad14d55c0b3765c55c5b78b946517c14438ad876ec0f7ac22792988bb6cd7837aa64334eb5f7c668d570cbf8134b7f7e87eefa95179ca11bedcdf420eb6df91") + create three.make_from_hex_string ("3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47") + create expected.make_from_hex_string ("14f365462bac9e4b1fd955049cd7320d0d4ce2cec67d60ee2011ec10879cdb60f61ec86bda440358278bb5592cce8bfddee8c57c1565cf47eb89854ecd76f341bf19bf326671aa1") + has := invert (one, two, three) + assert ("test invert 5", has and one ~ expected) + end + + test_probably_prime_1 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_integer (11) + val := probab_prime_p (one, 10) + assert ("test probably prime 1", val = 2) + end + + test_probably_prime_2 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_integer (2_147_483_647) + val := probab_prime_p (one, 10) + assert ("test probably prime 2", val = 1) + end + + test_probably_prime_3 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("2 305 843 009 213 693 951") + val := probab_prime_p (one, 10) + assert ("test probably prime 3", val = 1) + end + + test_probably_prime_4 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("59 604 644 783 353 249") + val := probab_prime_p (one, 10) + assert ("test probably prime 4", val = 1) + end + + test_probably_prime_5 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("43 143 988 327 398 957 279 342 419 750 374 600 193") + val := probab_prime_p (one, 10) + assert ("test probably prime 5", val = 1) + end + + test_probably_prime_6 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550077") + val := probab_prime_p (one, 10) + assert ("test probably prime 6", val = 1) + end + + test_probably_prime_7 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("236749577021714299526482794866680 9 233066409497699870112003149352380375124855230068487109373226251983") + val := probab_prime_p (one, 10) + assert ("test probably prime 7", val = 1) + end + + test_probably_prime_8 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("236749577021714299526482794866680 8 233066409497699870112003149352380375124855230068487109373226251983") + val := probab_prime_p (one, 10) + assert ("test probably prime 7", val = 0) + end + + test_gcdext_1 + local + one: INTEGER_X + two: INTEGER_X + four: INTEGER_X + five: INTEGER_X + expected_1: INTEGER_X + expected_2: INTEGER_X + do + create one.make_limbs (6) + create two.make_limbs (6) + create four.make_from_hex_string ("474c50aa 62d128fa b3b99224 0846a26e f58bf664") + create five.make_from_hex_string ("ffffffff ffffffff ffffffff ffffffff 7fffffff") + create expected_1.make_from_integer (1) + create expected_2.make_from_hex_string ("-00000000 04b547f5 df885395 a422bbce 998d2570 9019af3a") + gcdext (one, two, void, four, five) + assert ("test gcdext 1", one ~ expected_1 and two ~ expected_2) + end + + test_millerrabin_1 + local + one: INTEGER_X + val: INTEGER + do + create one.make_from_string ("2 305 843 009 213 693 951") + val := millerrabin (one, 10) + assert ("test probably prime 3", val = 1) + end + + test_powm_1 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + four: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_integer (0xd2) + create three.make_from_integer (0x7ffffffe) + create four.make_from_integer (0x7fffffff) + create expected.make_from_integer (1) + powm (one, two, three, four) + assert ("test powm 1", one ~ expected) + end + + test_powm_2 + local + one: INTEGER_X + two: INTEGER_X + three: INTEGER_X + four: INTEGER_X + expected: INTEGER_X + do + create one + create two.make_from_integer (0xd2) + create three.make_from_hex_string ("1ffffff ffffffffe") + create four.make_from_hex_string ("1fffffff ffffffff") + create expected.make_from_integer (0x1) + powm (one, two, three, four) + assert ("test powm 2", one ~ expected) + end + + test_probably_prime_isprime_1 + local + val: BOOLEAN + do + val := probab_prime_isprime (0x25) + assert ("test probably_prime_isprime 1", val) + end + + test_probably_prime_isprime_2 + local + val: BOOLEAN + do + val := probab_prime_isprime (0x31) + assert ("test probably_prime_isprime 2", not val) + end +end diff --git a/library/crypto/eapml/tests/test_integer_x_random.e b/library/crypto/eapml/tests/test_integer_x_random.e new file mode 100644 index 00000000..fca45896 --- /dev/null +++ b/library/crypto/eapml/tests/test_integer_x_random.e @@ -0,0 +1,82 @@ +note + description: "Summary description for {TEST_INTEGER_X_RANDOM}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_INTEGER_X_RANDOM + +inherit + EQA_TEST_SET + + INTEGER_X_RANDOM + undefine + default_create + end + +feature + test_urandomm_1 + local + one: INTEGER_X + two: MERSENNE_TWISTER_RNG + three: INTEGER_X + do + create one + create two.make + create three.make_from_hex_string ("1000 0000 0000 0000 0000 0000 0000 0000") + urandomm (one, two, three) + assert ("test urandomm 1", one.item [0] = 0x39bca874 and one.item [1] = 0x58d2754b and one.item [2] = 0x82902d2f and one.item [3] = 0x0647f3c3) + end + + test_urandomm_2 + local + one: INTEGER_X + two: MERSENNE_TWISTER_RNG + three: INTEGER_X + i: INTEGER + do + create one + create two.make + create three.make_from_hex_string ("1000 0000 0000 0000 0000 0000 0000 0000") + from + i := 0 + until + i = 1000 + loop + urandomm (one, two, three) + i := i + 1 + end + assert ("test urandomm 2", one.item [0] = 0x620764dc and one.item [1] = 0xe1fff273 and one.item [2] = 0x6a24317d and one.item [3] = 0x05d87e21) + end + + test_urandomm_3 + local + one: INTEGER_X + two: MERSENNE_TWISTER_RNG + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make + create three.make_from_hex_string ("1 00000000 00000000 0001b8fa 16dfab9a ca16b6b3") + create expected.make_from_hex_string ("72a8d0a2 fd530069 2ab48f9e f732f5c3 fa212b90") + urandomm (one, two, three) + assert ("test urandomm 3", one ~ expected) + end + + test_urandomm_4 + local + one: INTEGER_X + two: LINEAR_CONGRUENTIAL_RNG + three: INTEGER_X + expected: INTEGER_X + do + create one + create two.make (32) + create three.make_from_hex_string ("1 00000000 00000000 0001b8fa 16dfab9a ca16b6b3") + create expected.make_from_hex_string ("d960a1bf 841fd605 99811941 a122cb1a 323a7636") + urandomm (one, two, three) + assert ("test urandomm 4", one ~ expected) + end +end diff --git a/library/crypto/eapml/tests/test_limb_manipulation.e b/library/crypto/eapml/tests/test_limb_manipulation.e new file mode 100644 index 00000000..53a592fb --- /dev/null +++ b/library/crypto/eapml/tests/test_limb_manipulation.e @@ -0,0 +1,37 @@ +note + description: "Summary description for {TEST_LIMB_MANIPULATION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_LIMB_MANIPULATION + +inherit + EQA_TEST_SET + LIMB_MANIPULATION + undefine + default_create + end + +feature + test_modlimb_inverse_1 + local + inverse: NATURAL_32 + do + inverse := modlimb_invert (0x7fffffff) + assert ("test limb inverse 1", inverse = 0x7fffffff) + end + + test_extract_limb_left_1 + local + one: NATURAL_32 + two: NATURAL_32 + val: NATURAL_32 + do + one := 0x13579bdf + two := 0x2468ace0 + val := extract_limb (8, one, two) + assert ("test exctact limb left 1", val = 0x579bdf24) + end +end diff --git a/library/crypto/eapml/tests/test_randstruct_lc.e b/library/crypto/eapml/tests/test_randstruct_lc.e new file mode 100644 index 00000000..ef5527fd --- /dev/null +++ b/library/crypto/eapml/tests/test_randstruct_lc.e @@ -0,0 +1,85 @@ +note + description: "Summary description for {TEST_RANDSTRUCT_LC}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_RANDSTRUCT_LC + +inherit + EQA_TEST_SET + INTEGER_X_FACILITIES + undefine + default_create + end + +feature + test_randget_1 + local + struct: LINEAR_CONGRUENTIAL_RNG + target: SPECIAL [NATURAL_32] + do + create struct.make (16) + create target.make_filled (0, 16) + struct.randget (target, 0, 16 * 32) + assert ("test randget 1 1", target [0] = 0x9a13029c and target [1] = 0xa57f74f1 and target [2] = 0x4978d92b and target [3] = 0xfcd3c783) + assert ("test randget 1 2", target [4] = 0xc6815ba3 and target [5] = 0xd1c1fccc and target [6] = 0xdce6db9b and target [7] = 0xab842185) + assert ("test randget 1 3", target [8] = 0x7561a561 and target [9] = 0xd97b558c and target [10] = 0x38fe3b9c and target [11] = 0x18105699) + assert ("test randget 1 4", target [12] = 0x4aa55829 and target [13] = 0xd9eae640 and target [14] = 0xc2e62e2f and target [15] = 0x8157a727) + end + + test_randget_2 + local + struct: LINEAR_CONGRUENTIAL_RNG + target: SPECIAL [NATURAL_32] + do + create struct.make (128) + create target.make_filled (0, 16) + struct.randget (target, 0, 16 * 32) + assert ("test randget 2 1", target [0] = 0x42a99a0c and target [1] = 0x71fd8f07 and target [2] = 0x2aaf58a0 and target [3] = 0xaf66ba93) + assert ("test randget 2 2", target [4] = 0xec6b8425 and target [5] = 0x3507ca60 and target [6] = 0x64c9c175 and target [7] = 0x73cfa3c6) + assert ("test randget 2 3", target [8] = 0xa8e20278 and target [9] = 0x2cd68b8a and target [10] = 0xa131dec1 and target [11] = 0x53ea074c) + assert ("test randget 2 4", target [12] = 0x47581f73 and target [13] = 0xa53cc0eb and target [14] = 0x343532f8 and target [15] = 0x3cf5ac8c) + end + + test_randget_3 + local + struct: LINEAR_CONGRUENTIAL_RNG + target: SPECIAL [NATURAL_32] + i: INTEGER + do + create struct.make (128) + create target.make_filled (0, 4) + from + i := 0 + until + i = 1_000 + loop + struct.randget (target, 0, 4 * 32) + i := i + 1 + end + assert ("test randget 3", target [0] = 0x6cb70ec0 and target [1] = 0x7e6c8a80 and target [2] = 0x314b0a1c and target [3] = 0xf4f389af) + end + + test_randget_4 + local + one: SPECIAL [NATURAL_32] + struct: LINEAR_CONGRUENTIAL_RNG + do + create one.make_filled (0, 6) + create struct.make (32) + struct.randget (one, 0, 0xa1) + assert ("test randget 4 1", one [0] = 0xbaecd515 and one [1] = 0x13ae8ec6 and one [2] = 0x518c8090 and one [3] = 0x881ca077 and one [4] = 0x870b7134 and one [5] = 0x00000001) + struct.randget (one, 0, 0xa1) + assert ("test randget 4 2", one [0] = 0x323a7636 and one [1] = 0xa122cb1a and one [2] = 0x99811941 and one [3] = 0x841fd605 and one [4] = 0xd960a1bf and one [5] = 0x0) + end + + test_make_1 + local + struct: LINEAR_CONGRUENTIAL_RNG + do + create struct.make (32) + assert ("test make 1", struct.seed.seed.capacity = 2) + end +end diff --git a/library/crypto/eapml/tests/test_randstruct_mt.e b/library/crypto/eapml/tests/test_randstruct_mt.e new file mode 100644 index 00000000..7a2ca3b4 --- /dev/null +++ b/library/crypto/eapml/tests/test_randstruct_mt.e @@ -0,0 +1,46 @@ +note + description: "Summary description for {TEST_RANDSTRUCT_MT}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_RANDSTRUCT_MT + +inherit + EQA_TEST_SET + +feature + test_randget_1 + local + one: MERSENNE_TWISTER_RNG + target: SPECIAL [NATURAL_32] + do + create one.make + create target.make_filled (0, 16) + one.randget (target, 0, 16 * 32) + assert ("test randget 1 1", target [0] = 0x39bca874 and target [1] = 0x58d2754b and target [2] = 0x82902d2f and target [3] = 0x7647f3c3) + assert ("test randget 1 2", target [4] = 0x680bbdc8 and target [5] = 0x14b9c0e1 and target [6] = 0xd84a873b and target [7] = 0x6580d17d) + assert ("test randget 1 3", target [8] = 0xbf767863 and target [9] = 0x1eff7e89 and target [10] = 0xaa3dc18b and target [11] = 0x3c0d9fcf) + assert ("test randget 1 4", target [12] = 0x7a337236 and target [13] = 0xf58174d5 and target [14] = 0x6846aeb6 and target [15] = 0x18f204fe) + end + + test_randget_2 + local + one: MERSENNE_TWISTER_RNG + target: SPECIAL [NATURAL_32] + i: INTEGER + do + create one.make + create target.make_filled (0, 4) + from + i := 0 + until + i >= 1_000 + loop + one.randget (target, 0, 4 * 32) + i := i + 1 + end + assert ("test randget 2", target [0] = 0x620764dc and target [1] = 0xe1fff273 and target [2] = 0x6a24317d and target [3] = 0x65d87e21) + end +end diff --git a/library/crypto/eapml/tests/test_special_arithmetic.e b/library/crypto/eapml/tests/test_special_arithmetic.e new file mode 100644 index 00000000..f7a6d49c --- /dev/null +++ b/library/crypto/eapml/tests/test_special_arithmetic.e @@ -0,0 +1,463 @@ +note + description: "Summary description for {TEST_NUMBER_ARITHMETIC}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_SPECIAL_ARITHMETIC + +inherit + EQA_TEST_SET + SPECIAL_COMPARISON + undefine + default_create + end + SPECIAL_ARITHMETIC + undefine + default_create + end + +feature + test_add_1_1 + local + one: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + add_1 (item, 0, one, 0, 4, 1, carry) + assert ("Test add 1 1", item [0] = 0 and item [1] = 0 and item [2] = 0 and item [3] = 0 and carry.item = 1) + end + + test_add_1_2 + local + item: SPECIAL [NATURAL_32] + junk: CELL [NATURAL_32] + do + create junk.put (0) + create item.make_filled (0, 2) + item [0] := 0xcb101a11 + item [1] := 0xf00635d0 + add_1 (item, 0, item, 0, 2, 0x57cc11df, junk) + assert ("test add 1 2", item [0] = 0x22dc2bf0 and item [1] = 0xf00635d1 and junk.item = 0) + end + + test_add_1_3 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + junk: CELL [NATURAL_32] + do + create junk.put (0) + create one.make_filled (0, 4) + create two.make_filled (0, 2) + one [0] := 0xeeeeeeee + one [1] := 0xeeeeeeee + two [0] := 0xeeeeeeee + add_1 (one, 2, two, 1, 1, 0, junk) + assert ("test add 1 3", one [0] = 0xeeeeeeee and one [1] = 0xeeeeeeee and one [2] = 0x0 and one [3] = 0x0 and two [0] = 0xeeeeeeee and two [1] = 0x0 and junk.item = 0) + end + + test_add_1_4 + local + one: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + add_1 (item, 0, one, 0, 4, 1, carry) + assert ("Test add 1 4 1", item [0] = 0 and item [1] = 0 and item [2] = 0 and item [3] = 0 and carry.item = 1) + add_1 (item, 0, one, 0, 4, 0, carry) + assert ("Test add 1 4 2", item [0] = 0xffffffff and item [1] = 0xffffffff and item [2] = 0xffffffff and item [3] = 0xffffffff and carry.item = 0) + end + + test_add_n + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create item.make_filled (0, 4) + create one.make_filled (0xffffffff, 4) + create two.make_filled (0, 4) + one [3] := 0x0 + two [0] := 0x1 + add_n (item, 0, one, 0, two, 0, 4, carry) + assert ("Test add n", item [0] = 0 and item [1] = 0 and item [2] = 0 and item [3] = 1 and carry.item = 0) + end + + test_add_n_carry + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create item.make_filled (0, 4) + create one.make_filled (0xffffffff, 4) + create two.make_filled (0, 4) + two [0] := 0x1 + add_n (item, 0, one, 0, two, 0, 4, carry) + assert ("Test add n", item [0] = 0 and item [1] = 0 and item [2] = 0 and item [3] = 0 and carry.item = 1) + end + + test_add_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create item.make_filled (0, 4) + create one.make_filled (0xffffffff, 4) + create two.make_filled (0, 4) + one [3] := 0x0 + two [0] := 0x1 + add (item, 0, one, 0, one.count, two, 0, two.count, carry) + assert ("Test add n", item [0] = 0 and item [1] = 0 and item [2] = 0 and item [3] = 1 and carry.item = 0) + end + + test_add_2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + do + create carry.put (0) + create one.make_filled (0, 0xb) + create two.make_filled (0, 0xa) + create three.make_filled (0, 0x5) + two [0] := 0xee98e4a2 + two [1] := 0x8aec1812 + two [2] := 0xfc43f9bb + two [3] := 0x70d1ccc8 + two [4] := 0xc122bf19 + two [5] := 0xeb356bfb + two [6] := 0x77f53c1f + two [7] := 0xac9b2b87 + two [8] := 0x13524c02 + two [9] := 0x89136811 + three [0] := 0x9cd0d89d + three [1] := 0x7850c26c + three [2] := 0xba3e2571 + three [3] := 0x4706816a + three [4] := 0xa9993e36 + add (one, 0, two, 0, 0xa, three, 0, 0x5, carry) + assert ("test add 2", carry.item = 0 and one [0] = 0x8b69bd3f and one [1] = 0x033cda7f and one [2] = 0xb6821f2d and one [3] = 0xb7d84e33 and one [4] = 0x6abbfd4f and one [5] = 0xeb356bfc and one [6] = 0x77f53c1f and one [7] = 0xac9b2b87 and one [8] = 0x13524c02 and one [9] = 0x89136811) + end + + test_cmp_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + comp: INTEGER_32 + do + create one.make_filled (0xffffffff, 4) + create two.make_filled (0x90000000, 4) + comp := cmp (one, 0, two, 0, 4) + assert ("Test cmp 1", comp = 1) + end + + test_cmp_2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + comp: INTEGER_32 + do + create one.make_filled (0x90000000, 4) + create two.make_filled (0xffffffff, 4) + comp := cmp (one, 0, two, 0, 4) + assert ("Test cmp 2", comp = -1) + end + + test_cmp_3 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + comp: INTEGER_32 + do + create one.make_filled (0x80000000, 4) + create two.make_filled (0x80000000, 4) + assert ("Test cmp 3", comp = 0) + end + + test_mul_1 + local + one: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create item.make_filled (0, 4) + create one.make_filled (1, 4) + mul_1 (item, 0, one, 0, 4, 2, carry) + assert ("Test mul 1", item [0] = 2 and item [1] = 2 and item [2] = 2 and item [3] = 2 and carry.item = 0) + create item.make_filled (0, 4) + create one.make_filled (0xffffffff, 4) + mul_1 (item, 0, one, 0, 4, 0xffffffff, carry) + assert ("Test mul 1", item [0] = 0x1 and item [1] = 0xffffffff and item [2] = 0xffffffff and item [3] = 0xffffffff and carry.item = 0xfffffffe) + end + + test_mul_1_offsets + local + one: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create item.make_filled (0, 6) + create one.make_filled (1, 6) + item [0] := 0x10101010 + item [5] := 0x10101010 + mul_1 (item, 1, one, 1, 4, 2, carry) + assert ("Test mul 1 offsets", item [0] = 0x10101010 and item [1] = 2 and item [2] = 2 and item [3] = 2 and item [4] = 2 and item [5] = 0x10101010 and carry.item = 0) + create item.make_filled (0, 6) + create one.make_filled (0xffffffff, 6) + item [0] := 0x10101010 + item [5] := 0x10101010 + mul_1 (item, 1, one, 1, 4, 0xffffffff, carry) + assert ("Test mul 1 offsets", item [0] = 0x10101010 and item [1] = 1 and item [2] = 0xffffffff and item [3] = 0xffffffff and item [4] = 0xffffffff and item [5] = 0x10101010 and carry.item = 0xfffffffe) + end + + test_mul_n_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + target: SPECIAL [NATURAL_32] + do + create one.make_filled (0x77777777, 4) + create two.make_filled (0x0, 4) + two [0] := 0x2 + create target.make_filled (0, 8) + mul_n (target, 0, one, 0, two, 0, 4) + assert ("test mul n 1", target [0] = 0xeeeeeeee and target [1] = 0xeeeeeeee and target [2] = 0xeeeeeeee and target [3] = 0xeeeeeeee and target [4] = 0x0 and target [5] = 0x0 and target [6] = 0x0 and target [7] = 0x0) + end + + test_mul_basecase_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create item.make_filled (0, 8) + create one.make_filled (4, 4) + create two.make_filled (4, 4) + mul_basecase (item, 0, one, 0, one.count, two, 0, two.count) + assert ("test mul basecase", item [0] = 0x10 and item [1] = 0x20 and item [2] = 0x30 and item [3] = 0x40 and item [4] = 0x30 and item [5] = 0x20 and item [6] = 0x10 and item [7] = 0x0) + end + + test_sqr + local + one: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 8) + sqr_n (item, 0, one, 0, 4) + assert ("test sqr", item [0] = 0x00000001 and item [1] = 0x0 and item [2] = 0x0 and item [3] = 0x0 and item [4] = 0xfffffffe and item [5] = 0xffffffff and item [6] = 0xffffffff and item [7] = 0xffffffff) + end + + test_sub_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + borrow: CELL [NATURAL_32] + do + create borrow.put (0) + create one.make_filled (0, 0x12) + create two.make_filled (0xffffffff, 0x11) + two [0x10] := 0x000001ff + create three.make_filled (0, 0x10) + three [0] := 0x9e76fb15 + three [1] := 0x32e4e606 + three [2] := 0xb6d93fcc + three [3] := 0x621dd631 + three [4] := 0xa3a1f005 + three [5] := 0x19f28b09 + three [6] := 0x19a6800c + three [7] := 0xaf6e5a54 + three [8] := 0x37fae053 + three [9] := 0xad460fb3 + three [10] := 0xfb2a9d7c + three [11] := 0x9947e909 + three [12] := 0x2a7e14c9 + three [13] := 0xce163d50 + three [14] := 0x689f4fd7 + three [15] := 0x7231ea35 + sub (one, 0, two, 0, 0x11, three, 0, 0x10, borrow) + assert ("test sub 1 1", borrow.item = 0 and one [0] = 0x618904ea and one [1] = 0xcd1b19f9 and one [2] = 0x4926c033 and one [3] = 0x9de229ce) + assert ("test sub 1 2", one [4] = 0x5c5e0ffa and one [5] = 0xe60d74f6 and one [6] = 0xe6597ff3 and one [7] = 0x5091a5ab) + assert ("test sub 1 3", one [8] = 0xc8051fac and one [9] = 0x52b9f04c and one [10] = 0x04d56283 and one [11] = 0x66b816f6) + assert ("test sub 1 4", one [12] = 0xd581eb36 and one [13] = 0x31e9c2af and one [14] = 0x9760b028 and one [15] = 0x8dce15ca and one [16] = 0x000001ff) + end + + test_sub_1_1 + local + one: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + do + create carry.put (0) + create one.make_filled (0x11111111, 4) + sub_1 (one, 0 + 2, one, 0 + 2, 2, 0, carry) + assert ("test sub 1", one [0] = 0x11111111 and one [1] = 0x11111111 and one [2] = 0x11111111 and one [3] = 0x11111111 and carry.item = 0x0) + end + + test_sub_1_2 + local + one: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + do + create carry.put (0) + create one.make_filled (0, 4) + sub_1 (one, 3, one, 3, 1, 0, carry) + assert ("Test sub 1 2", one [0] = 0x0 and one [1] = 0x0 and one [2] = 0x0 and one [3] = 0x0 and carry.item = 0x0) + end + + test_sub_n + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + create carry.put (0) + create item.make_filled (0, 4) + create one.make_filled (0, 4) + create two.make_filled (0, 4) + two [0] := 1 + sub_n (item, 0, one, 0, two, 0, 4, carry) + assert ("Test sub", item [0] = 0xffffffff and item [1] = 0xffffffff and item [2] = 0xffffffff and item [3] = 0xffffffff and carry.item = 1) + end + + test_incr_u + local + item: SPECIAL [NATURAL_32] + do + create item.make_filled (0xffffffff, 4) + item [3] := 0 + incr_u (item, 0, 1) + assert ("Test incr u", item [0] = 0x0 and item [1] = 0x0 and item [2] = 0x0 and item [3] = 0x1) + end + + big_one: SPECIAL [NATURAL_32] + local + one: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 65) + one [0] := 0xffffffff one [1] := 0xffffffff one [2] := 0xffffffff one [3] := 0xffffffff + one [4] := 0xffffffff one [5] := 0xffffffff one [6] := 0xffffffff one [7] := 0x3fffffff + -- + one [36] := 0x00000000 one [37] := 0x00000000 one [38] := 0xc0000000 one [39] := 0xffffffff + one [40] := 0xffffffff one [41] := 0xffffffff one [42] := 0xffffffff one [43] := 0xffffffff + one [44] := 0xffffffff one [45] := 0xffffffff one [46] := 0xffffffff one [47] := 0xffffffff + one [48] := 0xffffffff one [49] := 0xffffffff one [50] := 0xffffffff one [51] := 0xffffffff + one [52] := 0xffffffff one [53] := 0xffffffff one [54] := 0xffffffff one [55] := 0xffffffff + one [56] := 0xffffffff one [57] := 0x01ffffff one [58] := 0x00000000 one [59] := 0x00000000 + one [63] := 0xffffffff one [64] := 0xffffffff + + Result := one + end + + big_two: SPECIAL [NATURAL_32] + local + two: SPECIAL [NATURAL_32] + do + create two.make_filled (0, 65) + two [0] := 0xffffffff + two [40] := 0x00000000 two [41] := 0x00000000 two [42] := 0x00000000 two [43] := 0xfff80000 + two [44] := 0xffffffff two [45] := 0xffffffff two [46] := 0xffffffff two [47] := 0xffffffff + two [48] := 0xffffffff two [49] := 0xffffffff two [50] := 0xffffffff two [51] := 0xffffffff + two [52] := 0xffffffff two [53] := 0xffffffff two [54] := 0xffffffff two [55] := 0xffffffff + two [56] := 0xffffffff two [57] := 0xffffffff two [58] := 0xffffffff two [59] := 0xffffffff + two [60] := 0xffffffff two [61] := 0xffffffff two [62] := 0xffffffff two [63] := 0xffffffff + two [64] := 0xffffffff + + Result := two + end + + test_kara_n_odd + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + ref: SPECIAL [NATURAL_32] + workspace: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + one := big_one + two := big_two + create ref.make_filled (0, 130) + ref [0] := 0x00000001 ref [1] := 0xffffffff ref [2] := 0xffffffff ref [3] := 0xffffffff + ref [4] := 0xffffffff ref [5] := 0xffffffff ref [6] := 0xffffffff ref [7] := 0xbfffffff + ref [8] := 0x3fffffff + ref [36] := 0x00000000 ref [37] := 0x00000000 ref [38] := 0x40000000 ref [39] := 0xc0000000 + ref [40] := 0xffffffff ref [41] := 0xffffffff ref [42] := 0xffffffff ref [43] := 0x0007ffff + ref [48] := 0x00000000 ref [49] := 0x00000000 ref [50] := 0x00000000 ref [51] := 0xfffe0000 + ref [52] := 0xffffffff ref [53] := 0xffffffff ref [54] := 0xffffffff ref [55] := 0xffffffff + ref [56] := 0xffffffff ref [57] := 0xfdffffff ref [58] := 0x01ffffff + ref [60] := 0x00000000 ref [61] := 0x00000000 ref [62] := 0x00000000 ref [63] := 0x00000001 + ref [64] := 0xffffffff ref [65] := 0xfffffffd + ref [72] := 0x40000000 + ref [80] := 0x00000000 ref [81] := 0x00000000 ref [82] := 0x00020000 + ref [100] := 0x00000000 ref [101] := 0xfffff000 ref [102] := 0xffffffff ref [103] := 0xbfffffff + ref [104] := 0xffffffff ref [105] := 0xffffffff ref [106] := 0x0007ffff ref [107] := 0x00000000 + ref [108] := 0xfff80000 ref [109] := 0xffffffff ref [110] := 0xffffffff ref [111] := 0xffffffff + ref [112] := 0xffffffff ref [113] := 0xffffffff ref [114] := 0xffffffff ref [115] := 0xffffffff + ref [116] := 0xffffffff ref [117] := 0xffffffff ref [118] := 0xffffffff ref [119] := 0xffffffff + ref [120] := 0xffffffff ref [121] := 0xffffffff ref [122] := 0x01ffffff + ref [124] := 0x00000000 ref [125] := 0x00000000 ref [126] := 0x00000000 ref [127] := 0x00000000 + ref [128] := 0xffffffff ref [129] := 0xffffffff + + create workspace.make_filled (0, 2 * 65 + 2 * 32) + create item.make_filled (0, 65 + 65) + kara_mul_n (item, 0, one, 0, two, 0, 65, workspace, 0) + assert ("Test kara mul n odd", item.same_items (ref, 0, 0, ref.count)) + end + + test_kara_n + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + ref: SPECIAL [NATURAL_32] + workspace: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + one := big_one + two := big_two + create ref.make_filled (0, 128) + ref [0] := 0x00000001 ref [1] := 0xffffffff ref [2] := 0xffffffff ref [3] := 0xffffffff + ref [4] := 0xffffffff ref [5] := 0xffffffff ref [6] := 0xffffffff ref [7] := 0xbfffffff + ref [8] := 0x3fffffff + ref [36] := 0x00000000 ref [37] := 0x00000000 ref [38] := 0x40000000 ref [39] := 0xc0000000 + ref [40] := 0xffffffff ref [41] := 0xffffffff ref [42] := 0xffffffff ref [43] := 0x0007ffff + ref [48] := 0x00000000 ref [49] := 0x00000000 ref [50] := 0x00000000 ref [51] := 0xfffe0000 + ref [52] := 0xffffffff ref [53] := 0xffffffff ref [54] := 0xffffffff ref [55] := 0xffffffff + ref [56] := 0xffffffff ref [57] := 0xfdffffff ref [58] := 0x01ffffff + ref [60] := 0x00000000 ref [61] := 0x00000000 ref [62] := 0x00000000 ref [63] := 0x00000001 + ref [64] := 0xfffffffd + ref [68] := 0x00000000 ref [69] := 0x00000000 ref [70] := 0x00000000 ref [71] := 0x40000000 + ref [80] := 0x00000000 ref [81] := 0x00000000 ref [82] := 0x00020000 + ref [100] := 0x00000000 ref [101] := 0xfffff000 ref [102] := 0xbfffffff ref [103] := 0xffffffff + ref [104] := 0xffffffff ref [105] := 0xffffffff ref [106] := 0x0007ffff ref [107] := 0xfff80000 + ref [108] := 0xffffffff ref [109] := 0xffffffff ref [110] := 0xffffffff ref [111] := 0xffffffff + ref [112] := 0xffffffff ref [113] := 0xffffffff ref [114] := 0xffffffff ref [115] := 0xffffffff + ref [116] := 0xffffffff ref [117] := 0xffffffff ref [118] := 0xffffffff ref [119] := 0xffffffff + ref [120] := 0xffffffff ref [121] := 0x01ffffff + ref [124] := 0x00000000 ref [125] := 0x00000000 ref [126] := 0x00000000 ref [127] := 0xffffffff + + create workspace.make_filled (0, 2 * 64 + 2 * 32) + create item.make_filled (0, 64 + 64) + kara_mul_n (item, 0, one, 0, two, 0, 64, workspace, 0) + assert ("Test kara mul n", item.same_items (ref, 0, 0, ref.count)) + end +end diff --git a/library/crypto/eapml/tests/test_special_division.e b/library/crypto/eapml/tests/test_special_division.e new file mode 100644 index 00000000..c43d5e81 --- /dev/null +++ b/library/crypto/eapml/tests/test_special_division.e @@ -0,0 +1,458 @@ +note + description: "Summary description for {TEST_NUMBER_DIVISION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_SPECIAL_DIVISION + +inherit + EQA_TEST_SET + EXCEPTION_MANAGER + undefine + default_create + end + SPECIAL_DIVISION + undefine + default_create + end + +feature + test_tdiv_qr_div_0 + local + divide_zero_exception: TUPLE [divide_zero_exception: BOOLEAN] + do + create divide_zero_exception + divide_func (divide_zero_exception) + assert ("test tdiv qr div 0", divide_zero_exception.divide_zero_exception) + end + + divide_func (divide_zero_exception: TUPLE [divide_zero_exception: BOOLEAN]) + local + retried: BOOLEAN + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + do + if not retried then + create item.make_filled (0, 1) + create one.make_filled (0, 1) + create two.make_filled (0, 1) + create three.make_filled (0, 1) + tdiv_qr (item, 0, one, 0, two, 0, 1, three, 0, 0) + end + rescue + retried := True + if attached {DIVIDE_BY_ZERO} last_exception then + divide_zero_exception.divide_zero_exception := True + end + retry + end + + test_tdiv_qr_div_1_1 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0xffffffff, 4) + create denominator.make_filled (0x77777777, 1) + create quotient.make_filled (0, 4) + create remainder.make_filled (0, 1) + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 1) + assert ("tdiv qr div 1 1", quotient [0] = 0x00000002 and quotient [1] = 0xb6db6db9 and quotient [2] = 0x24924926 and quotient [3] = 0x00000002 and remainder [0] = 0x11111111) + end + + test_tdiv_qr_div_2_1 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0xffffffff, 4) + create denominator.make_filled (0x77777777, 2) + create quotient.make_filled (0, 4) + create remainder.make_filled (0, 2) + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 2) + assert ("test tdiv qr div 2 1 quotient", quotient [0] = 0x92492494 and quotient [1] = 0x24924924 and quotient [2] = 0x00000002 and quotient [3] = 0x0) + assert ("test tdiv qr div 2 1 remainder", remainder [0] = 0x33333333 and remainder [1] = 0x33333333) + end + + test_tdiv_qr_div_big_1 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0xffffffff, 4) + create denominator.make_filled (0x77777777, 3) + create quotient.make_filled (0, 4) + create remainder.make_filled (0, 3) + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 3) + assert ("test tdiv qr div big 1 quotient", quotient [0] = 0x24924924 and quotient [1] = 0x00000002 and quotient [2] = 0x0 and quotient [3] = 0x0) + assert ("test tdiv qr div big 1 remainder", remainder [0] = 0x44444443 and remainder [1] = 0x44444445 and remainder [2] = 0x44444444) + end + + test_tdiv_qr_div_big_2 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0xffffffff, 4) + create denominator.make_filled (0x77777777, 4) + create quotient.make_filled (0, 4) + create remainder.make_filled (0, 4) + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 4) + assert ("test tdiv qr div big 2 quotient", quotient [0] = 0x000000002 and quotient [1] = 0x00000000 and quotient [2] = 0x00000000 and quotient [3] = 0x00000000) + assert ("test tdiv qr div big 2 remainder", remainder [0] = 0x11111111 and remainder [1] = 0x11111111 and remainder [2] = 0x11111111 and remainder [3] = 0x11111111) + end + + test_tdiv_qr_div_big_3 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0xffffffff, 4) + create denominator.make_filled (0x77777777, 4) + create quotient.make_filled (0x0, 4) + create remainder.make_filled (0x0, 4) + numerator [3] := 0 + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 4) + assert ("test tdiv qr div big 3 quotient", quotient [0] = 0x00000000 and quotient [1] = 0x00000000 and quotient [2] = 0x00000000) + assert ("test tdiv qr div big 3 remainder", remainder [0] = 0xffffffff and remainder [1] = 0xffffffff and remainder [2] = 0xffffffff and remainder [3] = 0x0) + end + + test_tdiv_qr_div_big_4 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0x80000000, 4) + create denominator.make_filled (0x80000000, 4) + create quotient.make_filled (0, 4) + create remainder.make_filled (0, 4) + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 4) + assert ("test tdiv qr div big 4 quotient", quotient [0] = 0x1 and quotient [1] = 0x0 and quotient [2] = 0x0 and quotient [3] = 0x0) + assert ("test tdiv qr div big 4 remainder", remainder [0] = 0x0 and remainder [1] = 0x0 and remainder [2] = 0x0 and remainder [3] = 0x0) + end + + test_tdiv_qr_div_big_5 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + quotient: SPECIAL [NATURAL_32] + remainder: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0x80000000, 4) + create denominator.make_filled (0x80000000, 4) + create quotient.make_filled (0, 4) + remainder := numerator + tdiv_qr (quotient, 0, remainder, 0, numerator, 0, 4, denominator, 0, 4) + assert ("test tdiv qr div big 4 quotient", quotient [0] = 0x1 and quotient [1] = 0x0 and quotient [2] = 0x0 and quotient [3] = 0x0) + assert ("test tdiv qr div big 4 remainder", remainder [0] = 0x0 and remainder [1] = 0x0 and remainder [2] = 0x0 and remainder [3] = 0x0) + end + + test_tdiv_qr_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + four: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 6) + create two.make_filled (0, 5) + create three.make_filled (0, 10) + create four.make_filled (0, 5) + three [0] := 0x9ee82ea8 + three [1] := 0x90eb9c01 + three [2] := 0x564096ef + three [3] := 0x14156137 + three [4] := 0xd359cd33 + three [5] := 0xe06ffa35 + three [6] := 0xfe887b52 + three [7] := 0x2a7b2b66 + three [8] := 0x56ad0915 + three [9] := 0x014fae42 + four [0] := 0xf58bf664 + four [1] := 0x0846a26e + four [2] := 0xb3b99224 + four [3] := 0x62d128fa + four [4] := 0x474c50aa + tdiv_qr (one, 0, two, 0, three, 0, 10, four, 0, 5) + assert ("test tdiv qr 1 1", one [0] = 0x9019af3a and one [1] = 0x998d2570 and one [2] = 0xa422bbce and one [3] = 0xdf885395 and one [4] = 0x04b547f5) + assert ("test tdiv qr 1 2", two [0] = 0x0 and two [1] = 0x0 and two [2] = 0x0 and two [3] = 0x0 and two [4] = 0x0) + end + + test_divrem_1_div_1 + local + one: SPECIAL [NATURAL_32] + rem: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + rem := divrem_1 (item, 0, one, 0, 4, 1) + assert ("Test divrem 1 div 1", item.same_items (one, 0, 0, 4) and rem = 0) + end + + test_divrem_1_div_0 + local + one: SPECIAL [NATURAL_32] + rem: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 4) + create item.make_filled (0, 4) + rem := divrem_1 (item, 0, one, 0, 4, 0x12345678) + assert ("Test divrem 1 div 0", item.same_items (one, 0, 0, 4) and rem = 0x0) + end + + test_divrem_1_1 + local + one: SPECIAL [NATURAL_32] + rem: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 4) + one [3] := 0x80000000 + create item.make_filled (0, 4) + rem := divrem_1 (item, 0, one, 0, 4, 4) + assert ("Test divrem 1", item [3] = 0x20000000 and item [2] = 0x00000000 and item [1] = 0x00000000 and item [0] = 0x00000000 and rem = 0) + end + + test_divrem_1_2 + local + one: SPECIAL [NATURAL_32] + rem: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0x80000000, 4) + create item.make_filled (0, 4) + rem := divrem_1 (item, 0, one, 0, 4, 4) + assert ("Test divrem 1 2", item [3] = 0x20000000 and item [2] = 0x20000000 and item [1] = 0x20000000 and item [0] = 0x20000000 and rem = 0) + end + + test_divrem_1_3 + local + one: SPECIAL [NATURAL_32] + rem: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + rem := divrem_1 (item, 0, one, 0, 4, 0x12345678) + assert ("Test divrem 1 3", item [0] = 0x040021bc and item [1] = 0x880003f8 and item [2] = 0x10000077 and item [3] = 0x0000000e and rem = 0x026b07df) + end + + test_divrem_1_4 + local + one: SPECIAL [NATURAL_32] + rem: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + rem := divrem_1 (item, 0, one, 0, 4, 0x87654321) + assert ("Test divrem 1 4", item [0] = 0x8bcb369f and item [1] = 0x04899bbd and item [2] = 0xe4089ae4 and item [3] = 0x00000001 and rem = 0x65c75880) + end + + test_divrem_2_1 + local + one: SPECIAL [NATURAL_32] + divisor: SPECIAL [NATURAL_32] + junk: NATURAL_32 + item: SPECIAL [NATURAL_32] + do + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + create divisor.make_filled (0x80000000, 2) + junk := divrem_2 (item, 0, one, 0, 4, divisor, 0) + assert ("Test divrem 2 1", item [0] = 00000001 and item [1] = 0xfffffffe and item [2] = 0x00000000 and item [3] = 0x00000000 and junk = 0x00000001) + assert ("Test divrem 2 1", one [0] = 0x7fffffff and one [1] = 0x7fffffff and one [2] = 0xffffffff and one [3] = 0xffffffff) + end + + test_divrem_2_2 + local + numerator: SPECIAL [NATURAL_32] + denominator: SPECIAL [NATURAL_32] + junk: NATURAL_32 + quotient: SPECIAL [NATURAL_32] + do + create numerator.make_filled (0xffffffff, 5) + numerator [0] := 0xfffffffe + numerator [4] := 0x00000001 + create denominator.make_filled (0xeeeeeeee, 2) + create quotient.make_filled (0x0, 5) + junk := divrem_2 (quotient, 0, numerator, 0, 5, denominator, 0) + assert ("test divrem 2 2", quotient [0] = 0x92492494 and quotient [1] = 0x24924924 and quotient [2] = 0x00000002 and quotient [3] = 0x0 and quotient [4] = 0x0) + assert ("test divrem 2 2", numerator [0] = 0x66666666 and numerator [1] = 0x66666666) + end + + test_limb_inverse_1 + local + one: NATURAL_32 + res: NATURAL_32 + do + one := 0x80000000 + res := limb_inverse (one) + assert ("test limb inverse 1", res = 0xffffffff) + end + + test_limb_inverse_2 + local + one: NATURAL_32 + res: NATURAL_32 + do + one := 0xffffffff + res := limb_inverse (one) + assert ("test limb inverse 2", res = 0x00000001) + end + + test_limb_inverse_3 + local + one: NATURAL_32 + res: NATURAL_32 + do + one := 0x91a2b3c0 + res := limb_inverse (one) + assert ("test limb inverse 3", res = 0xc200000e) + end + + test_mod_1_1 + local + one: SPECIAL [NATURAL_32] + val: CELL [NATURAL_32] + do + create val.put (0) + create one.make_filled (0, 5) + one [0] := 0x02f36db3 + one [1] := 0x00000009 + one [2] := 0xffffffff + one [3] := 0xffffffff + one [4] := 0xffffffff + mod_1 (one, 0, 2, 0x7b73add3, val) + assert ("test mod 1 1", val.item = 0x54d134dd) + end + + test_preinv_divrem_1 + local + one: SPECIAL [NATURAL_32] + junk: NATURAL_32 + do + create one.make_filled (0, 5) + one [1] := 0x87654321 + one [2] := 0xcccccccc + one [3] := 0x33333333 + one [4] := 0xffffffff + junk := preinv_divrem_1 (one, 0, 1, one, 1, 4, 0x3b9aca00, 0x12e0be82, 2) + assert ("test preinv divrem 1", one [0] = 0xfe8ef428 and one [1] = 0x273df9b7 and one [2] = 0x46093181 and one [3] = 0x4b82fa06 and one [4] = 0x00000004 and junk = 0x1B487000) + end + + test_preinv_divrem_2 + local + one: SPECIAL [NATURAL_32] + junk: NATURAL_32 + do + create one.make_filled (0, 5) + one [0] := 0xfe8ef428 + one [1] := 0x273df9b7 + one [2] := 0x46093181 + one [3] := 0x4b82fa06 + one [4] := 0x00000004 + junk := preinv_divrem_1 (one, 0, 1, one, 1, 4, 0x3b9aca00, 0x12e0be82, 2) + assert ("test preinv divrem 2", one [0] = 0x07fba954 and one [1] = 0x81c6f917 and one [2] = 0x725dd1c3 and one [3] = 0x00000012 and one [4] = 0x00000000 and junk = 0x33DBB800) + end + + test_preinv_divrem_3 + local + one: SPECIAL [NATURAL_32] + junk: NATURAL_32 + do + create one.make_filled (0, 9) + one [1] := 0x99811941 + one [2] := 0x841fd605 + one [3] := 0xd960a1bf + one [4] := 0x5e433efc + one [5] := 0x48c9bc93 + one [6] := 0x1c8b6fb1 + one [7] := 0x8ca06de0 + one [8] := 0xc6182337 + junk := preinv_divrem_1 (one, 0, 1, one, 1, 8, 0xcfd41b91, 0x3b563c24, 0) + assert ("test preinv divrem 2", one [0] = 0xb670b6b5 and one [1] = 0xf02cf008 and one [2] = 0x2a9327ab and one [3] = 0x2c16b429 and one [4] = 0x52cd5013 and one [5] = 0x2f45a033 and one [6] = 0x0fc1ade8 and one [7] = 0xf4026dfb and one [8] = 0x00000000 and junk = 0x1DFF6C7B) + end + + test_sb_divrem_mn_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + junk: NATURAL_32 + do + create one.make_filled (0xffffffff, 4) + create two.make_filled (0x80000000, 3) + create item.make_filled (0, 1) + junk := sb_divrem_mn (item, 0, one, 0, 4, two, 0, 3) + assert ("test sb divrem mn 1", item [0] = 0xfffffffe and one [1] = 0x00000000 and one [2] = 0x00000000 and one [3] = 0x7fffffff and junk = 0x1) + end + + test_sb_divrem_mn_2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + res: NATURAL_32 + do + create one.make_filled (0, 5) + create two.make_filled (0, 9) + create three.make_filled (0, 4) + two [4] := 0x348 + three [0] := 0xc50fb804 + three [1] := 0x4da1b404 + three [2] := 0xf47a2e7d + three [3] := 0x81d4eb6b + + res := sb_divrem_mn (one, 0, two, 0, 8, three, 0, 4) + assert ("test sb divrem mn 2", one [0] = 0x678 and one [1] = 0x0 and one [2] = 0x0 and one [3] = 0x0 and res = 0x0) + end + + test_sb_divrem_mn_3 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: NATURAL_32 + do + create one.make_filled (0, 6) + create two.make_filled (0, 10) + create three.make_filled (0, 5) + two [0] := 0x3dd05d50 + two [1] := 0x21d73803 + two [2] := 0xac812ddf + two [3] := 0x282ac26e + two [4] := 0xa6b39a66 + two [5] := 0xc0dff46b + two [6] := 0xfd10f6a5 + two [7] := 0x54f656cd + two [8] := 0xad5a122a + two [9] := 0x029f5c84 + three [0] := 0xeb17ecc8 + three [1] := 0x108d44dd + three [2] := 0x67732448 + three [3] := 0xc5a251f5 + three [4] := 0x8e98a154 + val := sb_divrem_mn (one, 0, two, 0, 10, three, 0, 5) + assert ("test sb divrem mn 3 1", one [0] = 0x9019af3a and one [1] = 0x998d2570 and one [2] = 0xa422bbce and one [3] = 0xdf885395 and one [4] = 0x04b547f5) + assert ("test sb divrem mn 3 2", two [0] = 0x0 and two [1] = 0x0 and two [2] = 0x0 and two [3] = 0x0 and two [4] = 0x0 and val = 0) + end +end diff --git a/library/crypto/eapml/tests/test_special_gcd.e b/library/crypto/eapml/tests/test_special_gcd.e new file mode 100644 index 00000000..e3f0321b --- /dev/null +++ b/library/crypto/eapml/tests/test_special_gcd.e @@ -0,0 +1,446 @@ +note + description: "Summary description for {TEST_NUMBER_GCD}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_SPECIAL_GCD + +inherit + EQA_TEST_SET + SPECIAL_GCD + undefine + default_create + end + +feature + test_basic_gcd_1 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + res: INTEGER_32 + do + create one_two.make_filled (0, 5) + create three.make_filled (0, 5) + one_two [0] := 0x7fffffff + one_two [1] := 0xffffffff + one_two [2] := 0xffffffff + one_two [3] := 0xffffffff + one_two [4] := 0xffffffff + three [0] := 0xbd62fd99 + three [1] := 0x0211a89b + three [2] := 0xacee6489 + three [3] := 0x98b44a3e + three [4] := 0x11d3142a + res := basic_gcd (one_two, 0, one_two, 0, 5, three, 0, 5) + assert ("test basic gcd_1", one_two [0] = 0x00000001 and one_two [1] = 0x00000000 and one_two [2] = 0xffffffff and one_two [3] = 0xffffffff and one_two [4] = 0xffffffff and res = 1) + end + + test_basic_gcd_2 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x6141c975 + three [1] := 0x22ddfba5 + three [2] := 0xa09fab66 + three [3] := 0x000075bd + val := basic_gcd (one_two, 0, one_two, 0, 4, three, 0, 4) + assert ("test basic gcd 2", one_two [0] = 0x1 and val = 1) + end + + test_basic_gcd_3 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x0be1f345 + three [1] := 0x0943df37 + three [2] := 0x0565ad11 + three [3] := 0x00001f3e + val := basic_gcd (one_two, 0, one_two, 0, 4, three, 0, 4) + assert ("test basic gcd 3", one_two [0] = 0x1 and val = 1) + end + + test_basic_gcd_4 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x8bb4ea3d + three [1] := 0x1f8bcda9 + three [2] := 0x25f7d40e + three [3] := 0x00002e40 + val := basic_gcd (one_two, 0, one_two, 0, 4, three, 0, 4) + assert ("test basic gcd 4", one_two [0] = 0x1 and val = 1) + end + + test_basic_gcd_5 + local + one_three: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_three.make_filled (0, 17) + create two.make_filled (0, 17) + two [0] := 0xd96a4395 + two [1] := 0xd77d6bb5 + two [2] := 0xff132ed5 + two [3] := 0xeca1c0e4 + two [4] := 0xb6df6c57 + two [5] := 0xfeb6912f + two [6] := 0xafb643b9 + two [7] := 0xc05dd8ec + two [8] := 0x12c61699 + two [9] := 0xd44be35a + two [10] := 0xb675f7ea + two [11] := 0x2ffd5545 + two [12] := 0xab960e36 + two [13] := 0xfd9a1223 + two [14] := 0xc5d32145 + two [15] := 0xb369d437 + two [16] := 0x000001ff + one_three [0] := 0xffffffff + one_three [1] := 0xffffffff + one_three [2] := 0xffffffff + one_three [3] := 0xffffffff + one_three [4] := 0xffffffff + one_three [5] := 0xffffffff + one_three [6] := 0xffffffff + one_three [7] := 0xffffffff + one_three [8] := 0xffffffff + one_three [9] := 0xffffffff + one_three [10] := 0xffffffff + one_three [11] := 0xffffffff + one_three [12] := 0xffffffff + one_three [13] := 0xffffffff + one_three [14] := 0xffffffff + one_three [15] := 0xffffffff + one_three [16] := 0x000001ff + val := basic_gcd (one_three, 0, two, 0, 17, one_three, 0, 17) + assert ("test basic gcd 5", one_three [0] = 0x1 and val = 1) + end + + test_div2_1 + local + r0: CELL [NATURAL_32] + r1: CELL [NATURAL_32] + val: NATURAL_32 + do + create r0.put (0) + create r1.put (0) + val := div2 (r0, r1, 0x55bf739f, 0xc3945435, 0x0fff167f, 0xf3e8e754) + assert ("test div2 1", r0.item = 0x0007cf91 and r1.item = 0x05c40320 and val = 0x5) + end + + test_div2_2 + local + r0: CELL [NATURAL_32] + r1: CELL [NATURAL_32] + val: NATURAL_32 + do + create r0.put (0) + create r1.put (0) + val := div2 (r0, r1, 0x9d001ff4, 0x08c14be0, 0x1f3e0565, 0xad110943) + assert ("test div2 2", r0.item = 0xa76c1d91 and r1.item = 0x00ca04f7 and val = 0x5) + end + + test_find_a + local + val: NATURAL_32 + do + val := find_a (0x68b82f95, 0xc45247ed) + assert ("test find a", val = 0x52aa2b12) + end + + test_nhgcd2_1 + local + five: SPECIAL [NATURAL_32] + val: BOOLEAN + do + create five.make_filled (0, 4) + val := nhgcd2 (0xdb7c2abf, 0x62e35e66, 0x75bda09f, 0xab6622dd, five) + assert ("test nhgcd2 1", val and five [0] = 0x02c85433 and five [1] = 0x0c43d237 and five [2] = 0x017e1f50 and five [3] = 0x0694540b) + end + + test_nhgcd2_2 + local + five: SPECIAL [NATURAL_32] + val: BOOLEAN + do + create five.make_filled (0, 4) + val := nhgcd2 (0xdb7c2abf, 0x62e35e66, 0x1f3e0565, 0xad110943, five) + assert ("test nhgcd2 2", val and five [0] = 0x15d545dd and five [1] = 0x088e653f and five [2] = 0x031b98c4 and five [3] = 0x0137c9e1) + end + + test_nhgcd2_3 + local + five: SPECIAL [NATURAL_32] + val: BOOLEAN + do + create five.make_filled (0, 4) + val := nhgcd2 (0xdb7c2abf, 0x62e35e66, 0x2e4025f7, 0xd40e1f8b, five) + assert ("test nhgcd2 3", val and five [0] = 0x3d89bb6b and five [1] = 0x2b76efa2 and five [2] = 0x0cf7ad20 and five [3] = 0x0928b403) + end + + test_nhgcd2_4 + local + five: SPECIAL [NATURAL_32] + val: BOOLEAN + do + create five.make_filled (0, 4) + val := nhgcd2 (0xdb7c2abf, 0x62e35e66, 0x0905a1c3, 0xf4cec73b, five) + assert ("test nhgcd2 4", val and five [0] = 0x411e611d and five [1] = 0x05ebcf53 and five [2] = 0x02ad3db7 and five [3] = 0x003e4ece) + end + + test_ngcd_lehmer_1 + local + one_three: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + four: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_three.make_filled (0, 7) + one_three [0] := 0x05fadced + one_three [1] := 0x01251177 + one_three [2] := 0x17eb73b4 + one_three [3] := 0x049445dc + create two.make_filled (0, 5) + two [0] := 0x236dc147 + two [1] := 0x0071f142 + two [2] := 0xffffffff + two [3] := 0xffffffff + two [4] := 0xffffffff + create four.make_filled (0, 6) + four [0] := 0x236dc147 + four [1] := 0x0071f142 + four [2] := 0x530b1a98 + four [3] := 0xbe9c1686 + four [4] := 0x9ecb20bd + four [5] := 0x000000df + val := ngcd_lehmer (one_three, 0, two, 0, one_three, 0, 2, four, 0) + assert ("test ngcd lehmer 1", one_three [0] = 0x1 and val = 1) + end + + test_ngcd_lehmer_2 + local + one_three: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + four: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_three.make_filled (0, 4) + create two.make_filled (0, 4) + create four.make_filled (0, 8) + one_three [0] := 0x6141c975 + one_three [1] := 0x22ddfba5 + one_three [2] := 0xa09fab66 + one_three [3] := 0x000075bd + two [0] := 0xbead208b + two [1] := 0x5e668076 + two [2] := 0x2abf62e3 + two [3] := 0x0000db7c + val := ngcd_lehmer (one_three, 0, two, 0, one_three, 0, 4, four, 0) + assert ("test ngcd lehmer 2", one_three [0] = 0x1 and val = 1) + end + + test_ngcd_lehmer_3 + local + one_three: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + four: SPECIAL [NATURAL_32] + val: INTEGER + do + create two.make_filled (0, 4) + create one_three.make_filled (0, 4) + create four.make_filled (0, 8) + two [0] := 0xbead208b + two [1] := 0x5e668076 + two [2] := 0x2abf62e3 + two [3] := 0x0000db7c + one_three [0] := 0x0be1f345 + one_three [1] := 0x0943df37 + one_three [2] := 0x0565ad11 + one_three [3] := 0x00001f3e + val := ngcd_lehmer (one_three, 0, two, 0, one_three, 0, 4, four, 0) + assert ("test ngcd lehmer 3", one_three [0] = 0x1 and val = 1) + end + + test_ngcd_lehmer_4 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + four: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + create four.make_filled (0, 8) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x8bb4ea3d + three [1] := 0x1f8bcda9 + three [2] := 0x25f7d40e + three [3] := 0x00002e40 + val := ngcd_lehmer (one_two, 0, one_two, 0, three, 0, 4, four, 0) + assert ("test ngcd lehmer 4", one_two [0] = 0x1 and val = 1) + end + + test_gcd_2_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + val: INTEGER + do + create one.make_filled (0, 2) + create two.make_filled (0, 2) + one [0] := 0x236dc147 + one [1] := 0x0071f142 + two [0] := 0x05fadced + two [1] := 0x01251177 + val := gcd_2 (one, 0, two, 0) + assert ("test gcd 2", val = 1 and one [0] = 0x1 and one [1] = 0x0) + end + + test_gcd_1_1 + local + one: SPECIAL [NATURAL_32] + val: NATURAL_32 + do + create one.make_filled (0, 2) + one [0] := 0x302ccd43 + one [1] := 0x0 + val := gcd_1 (one, 0, 1, 0xccd079fe) + assert ("test gcd 1 1", val = 0x1) + end + + test_gcd_1 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x6141c975 + three [1] := 0x22ddfba5 + three [2] := 0xa09fab66 + three [3] := 0x000075bd + val := gcd (one_two, 0, one_two, 0, 4, three, 0, 4) + assert ("test gcd 1", one_two [0] = 0x1 and one_two [1] = 0x0 and one_two [2] = 0x0 and one_two [3] = 0x0 and val = 1) + end + + test_gcd_2 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x0be1f345 + three [1] := 0x0943df37 + three [2] := 0x0565ad11 + three [3] := 0x00001f3e + val := gcd (one_two, 0, one_two, 0, 4, three, 0, 4) + assert ("test gcd 2", one_two [0] = 0x1 and val = 1) + end + + test_gcd_3 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_two.make_filled (0, 4) + create three.make_filled (0, 4) + one_two [0] := 0xbead208b + one_two [1] := 0x5e668076 + one_two [2] := 0x2abf62e3 + one_two [3] := 0x0000db7c + three [0] := 0x8bb4ea3d + three [1] := 0x1f8bcda9 + three [2] := 0x25f7d40e + three [3] := 0x00002e40 + val := gcd (one_two, 0, one_two, 0, 4, three, 0, 4) + assert ("test gcd 3", one_two [0] = 0x1 and val = 1) + end + + test_gcd_4 + local + one_three: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + val: INTEGER + do + create one_three.make_filled (0, 17) + create two.make_filled (0, 17) + two [0] := 0xd96a4395 + two [1] := 0xd77d6bb5 + two [2] := 0xff132ed5 + two [3] := 0xeca1c0e4 + two [4] := 0xb6df6c57 + two [5] := 0xfeb6912f + two [6] := 0xafb643b9 + two [7] := 0xc05dd8ec + two [8] := 0x12c61699 + two [9] := 0xd44be35a + two [10] := 0xb675f7ea + two [11] := 0x2ffd5545 + two [12] := 0xab960e36 + two [13] := 0xfd9a1223 + two [14] := 0xc5d32145 + two [15] := 0xb369d437 + two [16] := 0x000001ff + one_three [0] := 0xffffffff + one_three [1] := 0xffffffff + one_three [2] := 0xffffffff + one_three [3] := 0xffffffff + one_three [4] := 0xffffffff + one_three [5] := 0xffffffff + one_three [6] := 0xffffffff + one_three [7] := 0xffffffff + one_three [8] := 0xffffffff + one_three [9] := 0xffffffff + one_three [10] := 0xffffffff + one_three [11] := 0xffffffff + one_three [12] := 0xffffffff + one_three [13] := 0xffffffff + one_three [14] := 0xffffffff + one_three [15] := 0xffffffff + one_three [16] := 0x000001ff + val := gcd (one_three, 0, two, 0, 17, one_three, 0, 17) + assert ("test gcd 4", one_three [0] = 0x1 and val = 1) + end +end diff --git a/library/crypto/eapml/tests/test_special_logic.e b/library/crypto/eapml/tests/test_special_logic.e new file mode 100644 index 00000000..a1bcb5d7 --- /dev/null +++ b/library/crypto/eapml/tests/test_special_logic.e @@ -0,0 +1,252 @@ +note + description: "Summary description for {TEST_NUMBER_LOGIC}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_SPECIAL_LOGIC + +inherit + EQA_TEST_SET + SPECIAL_LOGIC + undefine + default_create + end + +feature + test_lshift_1 + local + one: SPECIAL [NATURAL_32] + item: SPECIAL [NATURAL_32] + carry: CELL [NATURAL_32] + do + create carry.put (0) + create one.make_filled (0xffffffff, 4) + create item.make_filled (0, 4) + lshift (item, 0, one, 0, 4, 8, carry) + assert ("Test lshift 1", item [0] = 0xffffff00 and item [1] = 0xffffffff and item [2] = 0xffffffff and item [3] = 0xffffffff and carry.item = 0xff) + end + + test_bit_xor_lshift_1 + -- Test if bit_xor_lshift copies lower limbs of op1 when entire limbs of 0 are shifted in to op2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 6) + create two.make_filled (0x66666666, 6) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 6, three, 0, 4, 37) + assert ("test bit xor lshift 1", one [0] = 0x66666666) + end + + test_bit_xor_lshift_2 + -- Test if bit_xor_lshift xors the lower partial part of op2 e.g. the first lower 27 bits in this case + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 6) + create two.make_filled (0x66666666, 6) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 6, three, 0, 4, 37) + assert ("test bit xor lshift 2", one [0] = 0x66666666 and one [1] = 0x33333326) + end + + test_bit_xor_lshift_3 + -- Test if bit_xor_lshift xors all limbs when there are enough from both op1 and op2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 6) + create two.make_filled (0x66666666, 6) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 6, three, 0, 4, 37) + assert ("test bit xor lshift 3", one [0] = 0x66666666 and one [1] = 0x33333326 and one [2] = 0x33333333 and one [3] = 0x33333333 and one [4] = 0x33333333) + end + + test_bit_xor_lshift_4 + -- Test if bit_xor_lshift xors the last part of the upper partial part of op2 e.g. the upper 5 bits in this case + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 6) + create two.make_filled (0x66666666, 6) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 6, three, 0, 4, 37) + assert ("test bit xor lshift 4", one [0] = 0x66666666 and one [1] = 0x33333326 and one [2] = 0x33333333 and one [3] = 0x33333333 and one [4] = 0x33333333 and one [5] = 0x66666673) + end + + test_bit_xor_lshift_5 + -- Test if bit_xor_lshift copies all extra limbs after op2 contents is exhausted + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 8) + create two.make_filled (0x66666666, 7) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 7, three, 0, 4, 37) + assert ("test bit xor lshift 5", one [0] = 0x66666666 and one [1] = 0x33333326 and one [2] = 0x33333333 and one [3] = 0x33333333 and one [4] = 0x33333333 and one [5] = 0x66666673 and one [6] = 0x66666666) + end + + test_bit_xor_lshift_6 + -- Test if bit_xor_lshift handles when op1 runs out of data before op2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 8) + create two.make_filled (0x66666666, 4) + create three.make_filled (0xaaaaaaaa, 6) + bit_xor_lshift (one, 0, two, 0, 4, three, 0, 6, 37) + assert ("test bit xor lshift 6", one [0] = 0x66666666 and one [1] = 0x33333326 and one [2] = 0x33333333 and one [3] = 0x33333333) + end + + test_bit_xor_lshift_7 + -- Test if bit_xor_lshift handles the shifted tail of op2 after op1 is consumed + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0x0, 8) + create two.make_filled (0x66666666, 4) + create three.make_filled (0xaaaaaaaa, 6) + bit_xor_lshift (one, 0, two, 0, 4, three, 0, 6, 37) + assert ("test bit xor lshift 7", one [0] = 0x66666666 and one [1] = 0x33333326 and one [2] = 0x33333333 and one [3] = 0x33333333 and one [4] = 0x55555555 and one [5] = 0x55555555 and one [6] = 0x55555555 and one [7] = 0x15) + end + + test_bit_xor_lshift_8 + -- Test when op1 and op2 are exhausted at the same time + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 8) + create two.make_filled (0x66666666, 5) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 5, three, 0, 4, 37) + assert ("test bit xor lshift 8", one [0] = 0x66666666 and one [1] = 0x33333326 and one [2] = 0x33333333 and one [3] = 0x33333333 and one [4] = 0x33333333 and one [5] = 0x15) + end + + test_bit_xor_lshift_9 + -- Test a normal xor + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 8) + create two.make_filled (0x66666666, 4) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 4, three, 0, 4, 0) + assert ("test bit xor lshift 9", one [0] = 0xcccccccc and one [1] = 0xcccccccc and one [2] = 0xcccccccc and one [3] = 0xcccccccc and one [4] = 0x0) + end + + test_bit_xor_lshift_10 + -- Test a tight fit xor + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 3) + create two.make_filled (0x66666666, 3) + create three.make_filled (0xaaaaaaaa, 2) + bit_xor_lshift (one, 0, two, 0, 3, three, 0, 2, 22) + assert ("test bit xor lshift 10", one [0] = 0xcce66666 and one [1] = 0xcccccccc and one [2] = 0x664ccccc) + end + + test_bit_xor_lshift_11 + -- Test a tight fit xor + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 4) + create two.make_filled (0x66666666, 4) + create three.make_filled (0xaaaaaaaa, 2) + bit_xor_lshift (one, 0, two, 0, 4, three, 0, 2, 22) + assert ("test bit xor lshift 11", one [0] = 0xcce66666 and one [1] = 0xcccccccc and one [2] = 0x664ccccc and one [3] = 0x66666666) + end + + test_bit_xor_lshift_12 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 8) + create two.make_filled (0x66666666, 4) + create three.make_filled (0xaaaaaaaa, 4) + bit_xor_lshift (one, 0, two, 0, 4, three, 0, 4, 1) + assert ("test bit xor lshift 12", one [0] = 0x33333332 and one [1] = 0x33333333 and one [2] = 0x33333333 and one [3] = 0x33333333 and one [4] = 0x1) + end + + test_bit_xor_lshift_13 + -- Test a normal xor + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 8) + create two.make_filled (0x66666666, 4) + create three.make_filled (0x0, 4) + three [0] := 0x12345678 + three [1] := 0xfedcba98 + three [2] := 0x13579bdf + three [3] := 0x2468ace0 + bit_xor_lshift (one, 0, two, 0, 4, three, 0, 4, 0) + assert ("test bit xor lshift 13", one [0] = 0x7452301e and one [1] = 0x98badcfe and one [2] = 0x7531fdb9 and one [3] = 0x420eca86) + end + + test_bit_xor_lshift_14 + -- Test xor with op1 as a zero size operand + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 8) + create two.make_filled (0x0, 0) + create three.make_filled (0x0, 4) + three [0] := 0x12345678 + three [1] := 0xfedcba98 + three [2] := 0x13579bdf + three [3] := 0x2468ace0 + bit_xor_lshift (one, 0, two, 0, 0, three, 0, 4, 0) + assert ("test bit xor lshift 14", one [0] = 0x12345678 and one [1] = 0xfedcba98 and one [2] = 0x13579bdf and one [3] = 0x2468ace0) + end + + test_bit_xor_lshift_15 + local + one_two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one_two.make_filled (0, 5) + create three.make_filled (0x0, 4) + one_two [0] := 0x201 + one_two [1] := 0x0 + one_two [2] := 0x0 + one_two [3] := 0x20000 + three [0] := 0x3562c10f + three [1] := 0xab1407d7 + three [2] := 0x616f35f4 + three [3] := 0x9d73 + bit_xor_lshift (one_two, 0, one_two, 0, 4, three, 0, 4, 2) + assert ("test bit xor lshift 15", one_two [0] = 0xd58b063d and one_two [1] = 0xac501f5c and one_two [2] = 0x85bcd7d2 and one_two [3] = 0x75cd) + end +end diff --git a/library/crypto/eapml/tests/test_special_number_theoretic.e b/library/crypto/eapml/tests/test_special_number_theoretic.e new file mode 100644 index 00000000..6b805bf5 --- /dev/null +++ b/library/crypto/eapml/tests/test_special_number_theoretic.e @@ -0,0 +1,146 @@ +note + description: "Summary description for {TEST_NUMBER_NUMBER_THEORETIC}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_SPECIAL_NUMBER_THEORETIC + +inherit + EQA_TEST_SET + SPECIAL_NUMBER_THEORETIC + undefine + default_create + end + +feature + test_gcdext_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + cofactor: SPECIAL [NATURAL_32] + target: SPECIAL [NATURAL_32] + cofactor_count: TUPLE [cofactor_count: INTEGER] + junk: INTEGER + do + create one.make_filled (0x80000000, 5) + create two.make_filled (0x80000000, 5) + one [4] := 0 + one [4] := 0 + create cofactor.make_filled (0, 4) + create target.make_filled (0, 4) + create cofactor_count + junk := gcdext (target, 0, cofactor, 0, cofactor_count, one, 0, 4, two, 0, 4) + assert ("test gcdext 1 gcd", target [0] = 0x80000000 and target [1] = 0x80000000 and target [2] = 0x80000000 and target [3] = 0x80000000) + assert ("test gcdext 1 cofactor", cofactor [0] = 0x00000001 and cofactor [1] = 0x00000000 and cofactor [2] = 0x00000000 and cofactor [3] = 0x00000000 and cofactor_count.cofactor_count = 0) + end + + test_gcdext_2 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + cofactor: SPECIAL [NATURAL_32] + target: SPECIAL [NATURAL_32] + cofactor_count: TUPLE [cofactor_count: INTEGER] + junk: INTEGER + do + create one.make_filled (0x80000000, 5) + create two.make_filled (0x20000000, 5) + one [4] := 0 + two [4] := 0 + create cofactor.make_filled (0, 4) + create target.make_filled (0, 4) + create cofactor_count + junk := gcdext (target, 0, cofactor, 0, cofactor_count, one, 0, 4, two, 0, 4) + assert ("test gcdext 2 gcd", target [0] = 0x20000000 and target [1] = 0x20000000 and target [2] = 0x20000000 and target [3] = 0x20000000) + assert ("test gcdext 2 cofactor", cofactor [0] = 0x00000001 and cofactor [1] = 0x00000000 and cofactor [2] = 0x00000000 and cofactor [3] = 0x00000000 and cofactor_count.cofactor_count = 0) + end + + test_gcdext_3 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: TUPLE [three: INTEGER] + four: SPECIAL [NATURAL_32] + six: SPECIAL [NATURAL_32] + val: INTEGER + do + create one.make_filled (0, 6) + create two.make_filled (0, 6) + create three + create four.make_filled (0, 6) + create six.make_filled (0, 6) + four [0] := 0x7fffffff + four [1] := 0xffffffff + four [2] := 0xffffffff + four [3] := 0xffffffff + four [4] := 0xffffffff + six [0] := 0xf58bf664 + six [1] := 0x0846a26e + six [2] := 0xb3b99224 + six [3] := 0x62d128fa + six [4] := 0x474c50aa + val := gcdext (one, 0, two, 0, three, four, 0, 5, six, 0, 5) + assert ("test gcdext 3 1", one [0] = 0x1 and one [1] = 0x0 and one [2] = 0x0 and one [3] = 0x0 and one [4] = 0x0 and one [5] = 0x0) + assert ("test gcdext 3 2", two [0] = 0xe117d157 and two [1] = 0xfe887b52 and two [2] = 0x2a7b2b66 and two [3] = 0x56ad0915 and two [4] = 0x014fae42 and two [5] = 0x00000000) + assert ("test gcdext 3 3", three.three = 5 and val = 1) + end + + test_basic_gcdext_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: TUPLE [three: INTEGER] + four: SPECIAL [NATURAL_32] + six: SPECIAL [NATURAL_32] + val: INTEGER + do + create one.make_filled (0, 6) + create two.make_filled (0, 6) + create three + create four.make_filled (0, 6) + create six.make_filled (0, 6) + four [0] := 0x7fffffff + four [1] := 0xffffffff + four [2] := 0xffffffff + four [3] := 0xffffffff + four [4] := 0xffffffff + six [0] := 0xf58bf664 + six [1] := 0x0846a26e + six [2] := 0xb3b99224 + six [3] := 0x62d128fa + six [4] := 0x474c50aa + val := basic_gcdext (one, 0, two, 0, three, four, 0, 5, six, 0, 5) + assert ("test basic gcdext 1 1", one [0] = 0x1 and one [1] = 0x0 and one [2] = 0x0 and one [3] = 0x0 and one [4] = 0x0 and one [5] = 0x0) + assert ("test basic gcdext 1 2", two [0] = 0xe117d157 and two [1] = 0xfe887b52 and two [2] = 0x2a7b2b66 and two [3] = 0x56ad0915 and two [4] = 0x014fae42 and two [5] = 0x00000000) + assert ("test basic gcdext 1 3", three.three = 5 and val = 1) + end + + test_gcdext_div2_1 + local + val: NATURAL_32 + do + val := gcdext_div2 (0xe9021704, 0x8d4d6a9f, 0x80000000, 0x0) + assert ("test gcdext div2 1", val = 0x1) + end + + test_invert_gf_1 + local + one: SPECIAL [NATURAL_32] + two: SPECIAL [NATURAL_32] + three: SPECIAL [NATURAL_32] + do + create one.make_filled (0, 4) + create two.make_filled (0, 4) + create three.make_filled (0, 4) + two [0] := 0x3562c10f + two [1] := 0xab1407d7 + two [2] := 0x616f35f4 + two [3] := 0x9d73 + three [0] := 0x201 + three [3] := 0x20000 + invert_gf (one, 0, two, 0, 4, three, 0, 4) + assert ("test invert gf 1", one [0] = 0x3e34792c and one [1] = 0xde538519 and one [2] = 0x9cd55090 and one [3] = 0xfa49) + end +end diff --git a/library/crypto/eapml/tests/tests-safe.ecf b/library/crypto/eapml/tests/tests-safe.ecf new file mode 100644 index 00000000..66210e3b --- /dev/null +++ b/library/crypto/eapml/tests/tests-safe.ecf @@ -0,0 +1,25 @@ + + + + + + + + + + + + /.svn$ + /EIFGENs$ + /CVS$ + /.hg$ + + + + + + + + diff --git a/library/crypto/eapml/tests/tests.ecf b/library/crypto/eapml/tests/tests.ecf new file mode 100644 index 00000000..d59a47ec --- /dev/null +++ b/library/crypto/eapml/tests/tests.ecf @@ -0,0 +1,29 @@ + + + + + + + + + + + /.hg$ + /EIFGENs$ + /CVS$ + /.svn$ + + + + + + + + + + + + + diff --git a/library/crypto/eapml/tests/tests.rc b/library/crypto/eapml/tests/tests.rc new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/library/crypto/eapml/tests/tests.rc @@ -0,0 +1 @@ + diff --git a/library/crypto/eel/.gitignore b/library/crypto/eel/.gitignore new file mode 100644 index 00000000..a7f9c034 --- /dev/null +++ b/library/crypto/eel/.gitignore @@ -0,0 +1 @@ +EIFGENs/ diff --git a/library/crypto/eel/RSA/rsa_key_pair.e b/library/crypto/eel/RSA/rsa_key_pair.e new file mode 100644 index 00000000..dc01e81b --- /dev/null +++ b/library/crypto/eel/RSA/rsa_key_pair.e @@ -0,0 +1,62 @@ +note + description: "Summary description for {RSA_KEY_PAIR}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "If you think health care is expensive now, wait until you see what it costs when it's free. - P.J. O'Rourke (1993)" + +class + RSA_KEY_PAIR + +inherit + DEBUG_OUTPUT + +create + make, + make_with_exponent + +feature {NONE} + make (bits: INTEGER) + local + e: INTEGER_X + p: INTEGER_X + q: INTEGER_X + n: INTEGER_X + p_bits: INTEGER + do + p_bits := (bits + 1) // 2 + create e.make_from_integer (65537) + create p.make_random_prime (p_bits) + create q.make_random_prime (bits - p_bits) + n := p * q + create public.make (n, e) + create private.make (p, q, n, e) + end + + make_with_exponent (bits: INTEGER e_a: INTEGER_X) + require + e_a.is_probably_prime + local + p: INTEGER_X + q: INTEGER_X + n: INTEGER_X + p_bits: INTEGER + do + p_bits := (bits + 1) // 2 + create p.make_random_prime (p_bits) + create q.make_random_prime (bits - p_bits) + n := p * q + create public.make (n, e_a) + create private.make (p, q, n, e_a) + end + +feature + public: RSA_PUBLIC_KEY + private: RSA_PRIVATE_KEY + +feature {NONE} --{DEBUG_OUTPUT} + debug_output: STRING + do + result := "P: " + private.p.debug_output + " Q: " + private.q.debug_output + " D: " + private.d.debug_output + " N: " + public.modulus.debug_output + " E: " + public.exponent.debug_output + end +end diff --git a/library/crypto/eel/RSA/rsa_private_key.e b/library/crypto/eel/RSA/rsa_private_key.e new file mode 100644 index 00000000..077a4b32 --- /dev/null +++ b/library/crypto/eel/RSA/rsa_private_key.e @@ -0,0 +1,46 @@ +note + description: "Summary description for {RSA_PRIVATE_KEY}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "If you have ten thousand regulations, you destroy all respect for the law. - Winston Churchill" + +class + RSA_PRIVATE_KEY + +create + make + +feature + make (p_a: INTEGER_X q_a: INTEGER_X n_a: INTEGER_X e_a: INTEGER_X) + local + phi: INTEGER_X + do + p := p_a + q := q_a + n := n_a + e := e_a + phi := (p - p.one) * (q - q.one) + d := e.inverse_value (phi) + end + + sign (message: INTEGER_X): INTEGER_X + do + result := decrypt (message) + end + + decrypt (cipher: INTEGER_X): INTEGER_X + do + result := cipher.powm_value (d, n) + end + +feature + p: INTEGER_X + q: INTEGER_X + d: INTEGER_X + n: INTEGER_X + e: INTEGER_X + +invariant + p * q ~ n +end diff --git a/library/crypto/eel/RSA/rsa_public_key.e b/library/crypto/eel/RSA/rsa_public_key.e new file mode 100644 index 00000000..18514acf --- /dev/null +++ b/library/crypto/eel/RSA/rsa_public_key.e @@ -0,0 +1,43 @@ +note + description: "Summary description for {RSA_KEY}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Tyranny is always better organized than freedom. - Charles Peguy" + +class + RSA_PUBLIC_KEY + +inherit + DEBUG_OUTPUT + +create + make + +feature + make (modulus_a: INTEGER_X exponent_a: INTEGER_X) + do + modulus := modulus_a + exponent := exponent_a + end + + verify (message: INTEGER_X signature: INTEGER_X): BOOLEAN + do + result := encrypt (signature) ~ message + end + + encrypt (message: INTEGER_X): INTEGER_X + do + result := message.powm_value (exponent, modulus) + end + +feature + modulus: INTEGER_X + exponent: INTEGER_X + +feature {RSA_KEY_PAIR}--{DEBUG_OUTPUT} + debug_output: STRING + do + result := "Modulus: 0x" + modulus.out_hex + end +end diff --git a/library/crypto/eel/aes/aes_common.e b/library/crypto/eel/aes/aes_common.e new file mode 100644 index 00000000..b4f3e2b0 --- /dev/null +++ b/library/crypto/eel/aes/aes_common.e @@ -0,0 +1,150 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Reader, suppose you were an idiot. And suppose you were a member of Congress. But I repeat myself. - Mark Twain" + +deferred class + AES_COMMON + +inherit + ROTATE_FACILITIES + +feature + S: SPECIAL [NATURAL_8] + -- The S box + once + create result.make_filled (0, 256) + result [0x00] := 0x63 result [0x01] := 0x7c result [0x02] := 0x77 result [0x03] := 0x7b result [0x04] := 0xf2 result [0x05] := 0x6b result [0x06] := 0x6f result [0x07] := 0xc5 + result [0x08] := 0x30 result [0x09] := 0x01 result [0x0a] := 0x67 result [0x0b] := 0x2b result [0x0c] := 0xfe result [0x0d] := 0xd7 result [0x0e] := 0xab result [0x0f] := 0x76 + result [0x10] := 0xca result [0x11] := 0x82 result [0x12] := 0xc9 result [0x13] := 0x7d result [0x14] := 0xfa result [0x15] := 0x59 result [0x16] := 0x47 result [0x17] := 0xf0 + result [0x18] := 0xad result [0x19] := 0xd4 result [0x1a] := 0xa2 result [0x1b] := 0xaf result [0x1c] := 0x9c result [0x1d] := 0xa4 result [0x1e] := 0x72 result [0x1f] := 0xc0 + result [0x20] := 0xb7 result [0x21] := 0xfd result [0x22] := 0x93 result [0x23] := 0x26 result [0x24] := 0x36 result [0x25] := 0x3f result [0x26] := 0xf7 result [0x27] := 0xcc + result [0x28] := 0x34 result [0x29] := 0xa5 result [0x2a] := 0xe5 result [0x2b] := 0xf1 result [0x2c] := 0x71 result [0x2d] := 0xd8 result [0x2e] := 0x31 result [0x2f] := 0x15 + result [0x30] := 0x04 result [0x31] := 0xc7 result [0x32] := 0x23 result [0x33] := 0xc3 result [0x34] := 0x18 result [0x35] := 0x96 result [0x36] := 0x05 result [0x37] := 0x9a + result [0x38] := 0x07 result [0x39] := 0x12 result [0x3a] := 0x80 result [0x3b] := 0xe2 result [0x3c] := 0xeb result [0x3d] := 0x27 result [0x3e] := 0xb2 result [0x3f] := 0x75 + result [0x40] := 0x09 result [0x41] := 0x83 result [0x42] := 0x2c result [0x43] := 0x1a result [0x44] := 0x1b result [0x45] := 0x6e result [0x46] := 0x5a result [0x47] := 0xa0 + result [0x48] := 0x52 result [0x49] := 0x3b result [0x4a] := 0xd6 result [0x4b] := 0xb3 result [0x4c] := 0x29 result [0x4d] := 0xe3 result [0x4e] := 0x2f result [0x4f] := 0x84 + result [0x50] := 0x53 result [0x51] := 0xd1 result [0x52] := 0x00 result [0x53] := 0xed result [0x54] := 0x20 result [0x55] := 0xfc result [0x56] := 0xb1 result [0x57] := 0x5b + result [0x58] := 0x6a result [0x59] := 0xcb result [0x5a] := 0xbe result [0x5b] := 0x39 result [0x5c] := 0x4a result [0x5d] := 0x4c result [0x5e] := 0x58 result [0x5f] := 0xcf + result [0x60] := 0xd0 result [0x61] := 0xef result [0x62] := 0xaa result [0x63] := 0xfb result [0x64] := 0x43 result [0x65] := 0x4d result [0x66] := 0x33 result [0x67] := 0x85 + result [0x68] := 0x45 result [0x69] := 0xf9 result [0x6a] := 0x02 result [0x6b] := 0x7f result [0x6c] := 0x50 result [0x6d] := 0x3c result [0x6e] := 0x9f result [0x6f] := 0xa8 + result [0x70] := 0x51 result [0x71] := 0xa3 result [0x72] := 0x40 result [0x73] := 0x8f result [0x74] := 0x92 result [0x75] := 0x9d result [0x76] := 0x38 result [0x77] := 0xf5 + result [0x78] := 0xbc result [0x79] := 0xb6 result [0x7a] := 0xda result [0x7b] := 0x21 result [0x7c] := 0x10 result [0x7d] := 0xff result [0x7e] := 0xf3 result [0x7f] := 0xd2 + result [0x80] := 0xcd result [0x81] := 0x0c result [0x82] := 0x13 result [0x83] := 0xec result [0x84] := 0x5f result [0x85] := 0x97 result [0x86] := 0x44 result [0x87] := 0x17 + result [0x88] := 0xc4 result [0x89] := 0xa7 result [0x8a] := 0x7e result [0x8b] := 0x3d result [0x8c] := 0x64 result [0x8d] := 0x5d result [0x8e] := 0x19 result [0x8f] := 0x73 + result [0x90] := 0x60 result [0x91] := 0x81 result [0x92] := 0x4f result [0x93] := 0xdc result [0x94] := 0x22 result [0x95] := 0x2a result [0x96] := 0x90 result [0x97] := 0x88 + result [0x98] := 0x46 result [0x99] := 0xee result [0x9a] := 0xb8 result [0x9b] := 0x14 result [0x9c] := 0xde result [0x9d] := 0x5e result [0x9e] := 0x0b result [0x9f] := 0xdb + result [0xa0] := 0xe0 result [0xa1] := 0x32 result [0xa2] := 0x3a result [0xa3] := 0x0a result [0xa4] := 0x49 result [0xa5] := 0x06 result [0xa6] := 0x24 result [0xa7] := 0x5c + result [0xa8] := 0xc2 result [0xa9] := 0xd3 result [0xaa] := 0xac result [0xab] := 0x62 result [0xac] := 0x91 result [0xad] := 0x95 result [0xae] := 0xe4 result [0xaf] := 0x79 + result [0xb0] := 0xe7 result [0xb1] := 0xc8 result [0xb2] := 0x37 result [0xb3] := 0x6d result [0xb4] := 0x8d result [0xb5] := 0xd5 result [0xb6] := 0x4e result [0xb7] := 0xa9 + result [0xb8] := 0x6c result [0xb9] := 0x56 result [0xba] := 0xf4 result [0xbb] := 0xea result [0xbc] := 0x65 result [0xbd] := 0x7a result [0xbe] := 0xae result [0xbf] := 0x08 + result [0xc0] := 0xba result [0xc1] := 0x78 result [0xc2] := 0x25 result [0xc3] := 0x2e result [0xc4] := 0x1c result [0xc5] := 0xa6 result [0xc6] := 0xb4 result [0xc7] := 0xc6 + result [0xc8] := 0xe8 result [0xc9] := 0xdd result [0xca] := 0x74 result [0xcb] := 0x1f result [0xcc] := 0x4b result [0xcd] := 0xbd result [0xce] := 0x8b result [0xcf] := 0x8a + result [0xd0] := 0x70 result [0xd1] := 0x3e result [0xd2] := 0xb5 result [0xd3] := 0x66 result [0xd4] := 0x48 result [0xd5] := 0x03 result [0xd6] := 0xf6 result [0xd7] := 0x0e + result [0xd8] := 0x61 result [0xd9] := 0x35 result [0xda] := 0x57 result [0xdb] := 0xb9 result [0xdc] := 0x86 result [0xdd] := 0xc1 result [0xde] := 0x1d result [0xdf] := 0x9e + result [0xe0] := 0xe1 result [0xe1] := 0xf8 result [0xe2] := 0x98 result [0xe3] := 0x11 result [0xe4] := 0x69 result [0xe5] := 0xd9 result [0xe6] := 0x8e result [0xe7] := 0x94 + result [0xe8] := 0x9b result [0xe9] := 0x1e result [0xea] := 0x87 result [0xeb] := 0xe9 result [0xec] := 0xce result [0xed] := 0x55 result [0xee] := 0x28 result [0xef] := 0xdf + result [0xf0] := 0x8c result [0xf1] := 0xa1 result [0xf2] := 0x89 result [0xf3] := 0x0d result [0xf4] := 0xbf result [0xf5] := 0xe6 result [0xf6] := 0x42 result [0xf7] := 0x68 + result [0xf8] := 0x41 result [0xf9] := 0x99 result [0xfa] := 0x2d result [0xfb] := 0x0f result [0xfc] := 0xb0 result [0xfd] := 0x54 result [0xfe] := 0xbb result [0xff] := 0x16 + end + + Si: SPECIAL [NATURAL_8] + -- S inverse box + once + create result.make_filled (0, 256) + result [0x00] := 0x52 result [0x01] := 0x09 result [0x02] := 0x6a result [0x03] := 0xd5 result [0x04] := 0x30 result [0x05] := 0x36 result [0x06] := 0xa5 result [0x07] := 0x38 + result [0x08] := 0xbf result [0x09] := 0x40 result [0x0a] := 0xa3 result [0x0b] := 0x9e result [0x0c] := 0x81 result [0x0d] := 0xf3 result [0x0e] := 0xd7 result [0x0f] := 0xfb + result [0x10] := 0x7c result [0x11] := 0xe3 result [0x12] := 0x39 result [0x13] := 0x82 result [0x14] := 0x9b result [0x15] := 0x2f result [0x16] := 0xff result [0x17] := 0x87 + result [0x18] := 0x34 result [0x19] := 0x8e result [0x1a] := 0x43 result [0x1b] := 0x44 result [0x1c] := 0xc4 result [0x1d] := 0xde result [0x1e] := 0xe9 result [0x1f] := 0xcb + result [0x20] := 0x54 result [0x21] := 0x7b result [0x22] := 0x94 result [0x23] := 0x32 result [0x24] := 0xa6 result [0x25] := 0xc2 result [0x26] := 0x23 result [0x27] := 0x3d + result [0x28] := 0xee result [0x29] := 0x4c result [0x2a] := 0x95 result [0x2b] := 0x0b result [0x2c] := 0x42 result [0x2d] := 0xfa result [0x2e] := 0xc3 result [0x2f] := 0x4e + result [0x30] := 0x08 result [0x31] := 0x2e result [0x32] := 0xa1 result [0x33] := 0x66 result [0x34] := 0x28 result [0x35] := 0xd9 result [0x36] := 0x24 result [0x37] := 0xb2 + result [0x38] := 0x76 result [0x39] := 0x5b result [0x3a] := 0xa2 result [0x3b] := 0x49 result [0x3c] := 0x6d result [0x3d] := 0x8b result [0x3e] := 0xd1 result [0x3f] := 0x25 + result [0x40] := 0x72 result [0x41] := 0xf8 result [0x42] := 0xf6 result [0x43] := 0x64 result [0x44] := 0x86 result [0x45] := 0x68 result [0x46] := 0x98 result [0x47] := 0x16 + result [0x48] := 0xd4 result [0x49] := 0xa4 result [0x4a] := 0x5c result [0x4b] := 0xcc result [0x4c] := 0x5d result [0x4d] := 0x65 result [0x4e] := 0xb6 result [0x4f] := 0x92 + result [0x50] := 0x6c result [0x51] := 0x70 result [0x52] := 0x48 result [0x53] := 0x50 result [0x54] := 0xfd result [0x55] := 0xed result [0x56] := 0xb9 result [0x57] := 0xda + result [0x58] := 0x5e result [0x59] := 0x15 result [0x5a] := 0x46 result [0x5b] := 0x57 result [0x5c] := 0xa7 result [0x5d] := 0x8d result [0x5e] := 0x9d result [0x5f] := 0x84 + result [0x60] := 0x90 result [0x61] := 0xd8 result [0x62] := 0xab result [0x63] := 0x00 result [0x64] := 0x8c result [0x65] := 0xbc result [0x66] := 0xd3 result [0x67] := 0x0a + result [0x68] := 0xf7 result [0x69] := 0xe4 result [0x6a] := 0x58 result [0x6b] := 0x05 result [0x6c] := 0xb8 result [0x6d] := 0xb3 result [0x6e] := 0x45 result [0x6f] := 0x06 + result [0x70] := 0xd0 result [0x71] := 0x2c result [0x72] := 0x1e result [0x73] := 0x8f result [0x74] := 0xca result [0x75] := 0x3f result [0x76] := 0x0f result [0x77] := 0x02 + result [0x78] := 0xc1 result [0x79] := 0xaf result [0x7a] := 0xbd result [0x7b] := 0x03 result [0x7c] := 0x01 result [0x7d] := 0x13 result [0x7e] := 0x8a result [0x7f] := 0x6b + result [0x80] := 0x3a result [0x81] := 0x91 result [0x82] := 0x11 result [0x83] := 0x41 result [0x84] := 0x4f result [0x85] := 0x67 result [0x86] := 0xdc result [0x87] := 0xea + result [0x88] := 0x97 result [0x89] := 0xf2 result [0x8a] := 0xcf result [0x8b] := 0xce result [0x8c] := 0xf0 result [0x8d] := 0xb4 result [0x8e] := 0xe6 result [0x8f] := 0x73 + result [0x90] := 0x96 result [0x91] := 0xac result [0x92] := 0x74 result [0x93] := 0x22 result [0x94] := 0xe7 result [0x95] := 0xad result [0x96] := 0x35 result [0x97] := 0x85 + result [0x98] := 0xe2 result [0x99] := 0xf9 result [0x9a] := 0x37 result [0x9b] := 0xe8 result [0x9c] := 0x1c result [0x9d] := 0x75 result [0x9e] := 0xdf result [0x9f] := 0x6e + result [0xa0] := 0x47 result [0xa1] := 0xf1 result [0xa2] := 0x1a result [0xa3] := 0x71 result [0xa4] := 0x1d result [0xa5] := 0x29 result [0xa6] := 0xc5 result [0xa7] := 0x89 + result [0xa8] := 0x6f result [0xa9] := 0xb7 result [0xaa] := 0x62 result [0xab] := 0x0e result [0xac] := 0xaa result [0xad] := 0x18 result [0xae] := 0xbe result [0xaf] := 0x1b + result [0xb0] := 0xfc result [0xb1] := 0x56 result [0xb2] := 0x3e result [0xb3] := 0x4b result [0xb4] := 0xc6 result [0xb5] := 0xd2 result [0xb6] := 0x79 result [0xb7] := 0x20 + result [0xb8] := 0x9a result [0xb9] := 0xdb result [0xba] := 0xc0 result [0xbb] := 0xfe result [0xbc] := 0x78 result [0xbd] := 0xcd result [0xbe] := 0x5a result [0xbf] := 0xf4 + result [0xc0] := 0x1f result [0xc1] := 0xdd result [0xc2] := 0xa8 result [0xc3] := 0x33 result [0xc4] := 0x88 result [0xc5] := 0x07 result [0xc6] := 0xc7 result [0xc7] := 0x31 + result [0xc8] := 0xb1 result [0xc9] := 0x12 result [0xca] := 0x10 result [0xcb] := 0x59 result [0xcc] := 0x27 result [0xcd] := 0x80 result [0xce] := 0xec result [0xcf] := 0x5f + result [0xd0] := 0x60 result [0xd1] := 0x51 result [0xd2] := 0x7f result [0xd3] := 0xa9 result [0xd4] := 0x19 result [0xd5] := 0xb5 result [0xd6] := 0x4a result [0xd7] := 0x0d + result [0xd8] := 0x2d result [0xd9] := 0xe5 result [0xda] := 0x7a result [0xdb] := 0x9f result [0xdc] := 0x93 result [0xdd] := 0xc9 result [0xde] := 0x9c result [0xdf] := 0xef + result [0xe0] := 0xa0 result [0xe1] := 0xe0 result [0xe2] := 0x3b result [0xe3] := 0x4d result [0xe4] := 0xae result [0xe5] := 0x2a result [0xe6] := 0xf5 result [0xe7] := 0xb0 + result [0xe8] := 0xc8 result [0xe9] := 0xeb result [0xea] := 0xbb result [0xeb] := 0x3c result [0xec] := 0x83 result [0xed] := 0x53 result [0xee] := 0x99 result [0xef] := 0x61 + result [0xf0] := 0x17 result [0xf1] := 0x2b result [0xf2] := 0x04 result [0xf3] := 0x7e result [0xf4] := 0xba result [0xf5] := 0x77 result [0xf6] := 0xd6 result [0xf7] := 0x26 + result [0xf8] := 0xe1 result [0xf9] := 0x69 result [0xfa] := 0x14 result [0xfb] := 0x63 result [0xfc] := 0x55 result [0xfd] := 0x21 result [0xfe] := 0x0c result [0xff] := 0x7d + end + + inv_sub_bytes (in: NATURAL_32): NATURAL_32 + do + result := si [((in |>> 24) & 0xff).to_integer_32].to_natural_32 |<< 24 + result := result | (si [((in |>> 16) & 0xff).to_integer_32].to_natural_32 |<< 16) + result := result | (si [((in |>> 8) & 0xff).to_integer_32].to_natural_32 |<< 8) + result := result | (si [(in & 0xff).to_integer_32]).to_natural_32 + ensure + (result & 0xff).to_natural_8 = si [(in & 0xff).to_integer_32] + ((result |>> 8) & 0xff).to_natural_8 = si [((in |>> 8) & 0xff).to_integer_32] + ((result |>> 16) & 0xff).to_natural_8 = si [((in |>> 16) & 0xff).to_integer_32] + (result |>> 24).to_natural_8 = si [((in |>> 24) & 0xff).to_integer_32] + end + + sub_bytes (in: NATURAL_32): NATURAL_32 + do + result := s [((in |>> 24) & 0xff).to_integer_32].to_natural_32 |<< 24 + result := result | (s [((in |>> 16) & 0xff).to_integer_32].to_natural_32 |<< 16) + result := result | (s [((in |>> 8) & 0xff).to_integer_32].to_natural_32 |<< 8) + result := result | (s [(in & 0xff).to_integer_32]) + ensure + (result & 0xff).to_natural_8 = s [(in & 0xff).to_integer_32] + ((result |>> 8) & 0xff).to_natural_8 = s [((in |>> 8) & 0xff).to_integer_32] + ((result |>> 16) & 0xff).to_natural_8 = s [((in |>> 16) & 0xff).to_integer_32] + (result |>> 24).to_natural_8 = s [((in |>> 24) & 0xff).to_integer_32] + end + + FFmulX (x: NATURAL_32): NATURAL_32 + do + result := ((x & m2) |<< 1).bit_xor (((x & m1) |>> 7) * m3) + end + + m1: NATURAL_32 = 0x80808080 + m2: NATURAL_32 = 0x7f7f7f7f + m3: NATURAL_32 = 0x0000001b + +feature + s_box_inverse: BOOLEAN + local + counter: INTEGER + do + from + counter := 0 + result := true + until + counter > 255 or not result + loop + result := si [s [counter].to_integer_32].to_integer_32 = counter + counter := counter + 1 + end + end + + s_box_inverse_once: BOOLEAN + -- Is the s-box correct as long as nothing modifies it + once + result := s_box_inverse + end + +invariant + s_box_inverse: s_box_inverse_once +end diff --git a/library/crypto/eel/aes/aes_engine.e b/library/crypto/eel/aes/aes_engine.e new file mode 100644 index 00000000..16458265 --- /dev/null +++ b/library/crypto/eel/aes/aes_engine.e @@ -0,0 +1,531 @@ +note + description: "Tagging class for various size/speed tradeoffs of AES" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Talk is cheap - except when Congress does it. - Cullen Hightower" + +deferred class + AES_ENGINE + +inherit + AES_COMMON + BYTE_FACILITIES + +feature + make_tables + do + two_table := multiply_table (0x2) + three_table := multiply_table (0x3) + nine_table := multiply_table (0x9) + eleven_table := multiply_table (0xb) + thirteen_table := multiply_table (0xd) + fourteen_table := multiply_table (0xe) + end + + block_size: INTEGER = 16 + +feature + mcol (x: NATURAL_32): NATURAL_32 + local + f2: NATURAL_32 + do + f2 := FFmulX (x) + result := f2.bit_xor (rotate_right_32 (x.bit_xor (f2), 8)).bit_xor (rotate_right_32 (x, 16)).bit_xor (rotate_right_32 (x, 24)) + end + + -- State matrix columns + column_0: NATURAL_32 + column_1: NATURAL_32 + column_2: NATURAL_32 + column_3: NATURAL_32 + +feature --Prepare input blocks for processing and return + unpack (bytes: SPECIAL [NATURAL_8] offset: INTEGER) + require + bytes.valid_index (offset) + bytes.valid_index (offset + 15) + local + index: INTEGER + do + index := bytes.lower + column_0 := as_natural_32_be (bytes, offset + index) + column_1 := as_natural_32_be (bytes, offset + index + 4) + column_2 := as_natural_32_be (bytes, offset + index + 8) + column_3 := as_natural_32_be (bytes, offset + index + 12) + ensure + bytes_match_blocks (bytes) + end + + pack (bytes: SPECIAL [NATURAL_8] offset: INTEGER) + require + bytes.valid_index (offset) + bytes.valid_index (offset + 15) + local + index: INTEGER + do + index := bytes.lower + from_natural_32_be (column_0, bytes, offset + index) + from_natural_32_be (column_1, bytes, offset + index + 4) + from_natural_32_be (column_2, bytes, offset + index + 8) + from_natural_32_be (column_3, bytes, offset + index + 12) + ensure + bytes_match_blocks (bytes) + end + + bytes_match_blocks (bytes: SPECIAL [NATURAL_8]): BOOLEAN + do + result := true + result := result and bytes [0] = (column_0 |>> 24 & 0xff).to_natural_8 + result := result and bytes [1] = (column_0 |>> 16 & 0xff).to_natural_8 + result := result and bytes [2] = (column_0 |>> 8 & 0xff).to_natural_8 + result := result and bytes [3] = (column_0 & 0xff).to_natural_8 + result := result and bytes [4] = (column_1 |>> 24 & 0xff).to_natural_8 + result := result and bytes [5] = (column_1 |>> 16 & 0xff).to_natural_8 + result := result and bytes [6] = (column_1 |>> 8 & 0xff).to_natural_8 + result := result and bytes [7] = (column_1 & 0xff).to_natural_8 + result := result and bytes [8] = (column_2 |>> 24 & 0xff).to_natural_8 + result := result and bytes [9] = (column_2 |>> 16 & 0xff).to_natural_8 + result := result and bytes [10] = (column_2 |>> 8 & 0xff).to_natural_8 + result := result and bytes [11] = (column_2 & 0xff).to_natural_8 + result := result and bytes [12] = (column_3 |>> 24 & 0xff).to_natural_8 + result := result and bytes [13] = (column_3 |>> 16 & 0xff).to_natural_8 + result := result and bytes [14] = (column_3 |>> 8 & 0xff).to_natural_8 + result := result and bytes [15] = (column_3 & 0xff).to_natural_8 + ensure + bytes [0] = (column_0 & 0xff).to_natural_8 + bytes [1] = (column_0 |>> 8 & 0xff).to_natural_8 + bytes [2] = (column_0 |>> 16 & 0xff).to_natural_8 + bytes [3] = (column_0 |>> 24 & 0xff).to_natural_8 + bytes [4] = (column_1 & 0xff).to_natural_8 + bytes [5] = (column_1 |>> 8 & 0xff).to_natural_8 + bytes [6] = (column_1 |>> 16 & 0xff).to_natural_8 + bytes [7] = (column_1 |>> 24 & 0xff).to_natural_8 + bytes [8] = (column_2 & 0xff).to_natural_8 + bytes [9] = (column_2 |>> 8 & 0xff).to_natural_8 + bytes [10] = (column_2 |>> 16 & 0xff).to_natural_8 + bytes [11] = (column_2 |>> 24 & 0xff).to_natural_8 + bytes [12] = (column_3 & 0xff).to_natural_8 + bytes [13] = (column_3 |>> 8 & 0xff).to_natural_8 + bytes [14] = (column_3 |>> 16 & 0xff).to_natural_8 + bytes [15] = (column_3 |>> 24 & 0xff).to_natural_8 + end + +feature + encrypt_work (max_index: INTEGER) + local + index: INTEGER + do + add_round_key (index) + from + index := 4 + until + index >= max_index - 4 + loop + sub_columns + shift_rows + mix_columns + add_round_key (index) + index := index + 4 + variant + max_index - index + 2 + end + sub_columns + shift_rows + add_round_key (index) + end + + decrypt_work (max_index: INTEGER) + local + index: INTEGER + do + index := max_index - 3 + add_round_key (index) + from + index := index - 4 + until + index = 0 + loop + inv_shift_rows + inv_sub_columns + add_round_key (index) + inv_mix_columns + index := index - 4 + variant + index + 1 + end + inv_shift_rows + inv_sub_columns + add_round_key (index) + end + + inv_sub_columns + do + column_0 := inv_sub_bytes (column_0) + column_1 := inv_sub_bytes (column_1) + column_2 := inv_sub_bytes (column_2) + column_3 := inv_sub_bytes (column_3) + end + + inv_mix_columns + do + column_0 := inv_mix_column (column_0) + column_1 := inv_mix_column (column_1) + column_2 := inv_mix_column (column_2) + column_3 := inv_mix_column (column_3) + end + + mix_columns + do + column_0 := mix_column (column_0) + column_1 := mix_column (column_1) + column_2 := mix_column (column_2) + column_3 := mix_column (column_3) + end + + inv_mix_column (in: NATURAL_32): NATURAL_32 + do + result := inv_mix_0 (in) + result := result | inv_mix_1 (in) + result := result | inv_mix_2 (in) + result := result | inv_mix_3 (in) + end + + inv_mix_0 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0xe) + part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0xb) + part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0xd) + part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0x9) + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 24 + end + + inv_mix_1 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0x9) + part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0xe) + part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0xb) + part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0xd) + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 16 + end + + inv_mix_2 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0xd) + part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0x9) + part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0xe) + part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0xb) + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 8 + end + + inv_mix_3 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0xb) + part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0xd) + part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0x9) + part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0xe) + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) + end + + mix_column (in: NATURAL_32): NATURAL_32 + do + result := mix_0 (in) + result := result | mix_1 (in) + result := result | mix_2 (in) + result := result | mix_3 (in) + end + + mix_0 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0x2) + part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0x3) + part_2 := in |>> 8 & 0xff + part_3 := in & 0xff + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 24 + end + + mix_1 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := (in |>> 24 & 0xff) + part_1 := multiply_and_reduce ((in |>> 16 & 0xff).to_natural_8, 0x2) + part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0x3) + part_3 := in & 0xff + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 16 + end + + mix_2 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := in |>> 24 & 0xff + part_1 := in |>> 16 & 0xff + part_2 := multiply_and_reduce ((in |>> 8 & 0xff).to_natural_8, 0x2) + part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0x3) + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) |<< 8 + end + + mix_3 (in: NATURAL_32): NATURAL_32 + local + part_0: NATURAL_32 + part_1: NATURAL_32 + part_2: NATURAL_32 + part_3: NATURAL_32 + do + part_0 := multiply_and_reduce ((in |>> 24 & 0xff).to_natural_8, 0x3) + part_1 := in |>> 16 & 0xff + part_2 := in |>> 8 & 0xff + part_3 := multiply_and_reduce ((in & 0xff).to_natural_8, 0x2) + result := part_0.bit_xor (part_1).bit_xor (part_2).bit_xor (part_3) + end + + sub_columns + do + column_0 := sub_bytes (column_0) + column_1 := sub_bytes (column_1) + column_2 := sub_bytes (column_2) + column_3 := sub_bytes (column_3) + end + + inv_shift_rows + local + column_0_new: NATURAL_32 + column_1_new: NATURAL_32 + column_2_new: NATURAL_32 + column_3_new: NATURAL_32 + do + column_0_new := column_0 & 0xff000000 + column_0_new := column_0_new | (column_3 & 0x00ff0000) + column_0_new := column_0_new | (column_2 & 0x0000ff00) + column_0_new := column_0_new | (column_1 & 0x000000ff) + column_1_new := column_1 & 0xff000000 + column_1_new := column_1_new | (column_0 & 0x00ff0000) + column_1_new := column_1_new | (column_3 & 0x0000ff00) + column_1_new := column_1_new | (column_2 & 0x000000ff) + column_2_new := column_2 & 0xff000000 + column_2_new := column_2_new | (column_1 & 0x00ff0000) + column_2_new := column_2_new | (column_0 & 0x0000ff00) + column_2_new := column_2_new | (column_3 & 0x000000ff) + column_3_new := column_3 & 0xff000000 + column_3_new := column_3_new | (column_2 & 0x00ff0000) + column_3_new := column_3_new | (column_1 & 0x0000ff00) + column_3_new := column_3_new | (column_0 & 0x000000ff) + column_0 := column_0_new + column_1 := column_1_new + column_2 := column_2_new + column_3 := column_3_new + ensure + column_0 |>> 24 & 0xff = old column_0 |>> 24 & 0xff + column_0 |>> 16 & 0xff = old column_3 |>> 16 & 0xff + column_0 |>> 8 & 0xff = old column_2 |>> 8 & 0xff + column_0 & 0xff = old column_1 & 0xff + column_1 |>> 24 & 0xff = old column_1 |>> 24 & 0xff + column_1 |>> 16 & 0xff = old column_0 |>> 16 & 0xff + column_1 |>> 8 & 0xff = old column_3 |>> 8 & 0xff + column_1 & 0xff = old column_2 & 0xff + column_2 |>> 24 & 0xff = old column_2 |>> 24& 0xff + column_2 |>> 16 & 0xff = old column_1 |>> 16 & 0xff + column_2 |>> 8 & 0xff = old column_0 |>> 8 & 0xff + column_2 & 0xff = old column_3 & 0xff + column_3 |>> 24& 0xff = old column_3 |>> 24 & 0xff + column_3 |>> 16 & 0xff = old column_2 |>> 16 & 0xff + column_3 |>> 8 & 0xff = old column_1 |>> 8 & 0xff + column_3 & 0xff = old column_0 & 0xff + end + + shift_rows + local + column_0_new: NATURAL_32 + column_1_new: NATURAL_32 + column_2_new: NATURAL_32 + column_3_new: NATURAL_32 + do + column_0_new := column_0 & 0xff000000 + column_0_new := column_0_new | (column_1 & 0x00ff0000) + column_0_new := column_0_new | (column_2 & 0x0000ff00) + column_0_new := column_0_new | (column_3 & 0x000000ff) + column_1_new := column_1 & 0xff000000 + column_1_new := column_1_new | (column_2 & 0x00ff0000) + column_1_new := column_1_new | (column_3 & 0x0000ff00) + column_1_new := column_1_new | (column_0 & 0x000000ff) + column_2_new := column_2 & 0xff000000 + column_2_new := column_2_new | (column_3 & 0x00ff0000) + column_2_new := column_2_new | (column_0 & 0x0000ff00) + column_2_new := column_2_new | (column_1 & 0x000000ff) + column_3_new := column_3 & 0xff000000 + column_3_new := column_3_new | (column_0 & 0x00ff0000) + column_3_new := column_3_new | (column_1 & 0x0000ff00) + column_3_new := column_3_new | (column_2 & 0x000000ff) + column_0 := column_0_new + column_1 := column_1_new + column_2 := column_2_new + column_3 := column_3_new + ensure + column_0 |>> 24 & 0xff = old column_0 |>> 24 & 0xff + column_0 |>> 16 & 0xff = old column_1 |>> 16 & 0xff + column_0 |>> 8 & 0xff = old column_2 |>> 8 & 0xff + column_0 & 0xff = old column_3 & 0xff + column_1 |>> 24 & 0xff = old column_1 |>> 24 & 0xff + column_1 |>> 16 & 0xff = old column_2 |>> 16 & 0xff + column_1 |>> 8 & 0xff = old column_3 |>> 8 & 0xff + column_1 & 0xff = old column_0 & 0xff + column_2 |>> 24 & 0xff = old column_2 |>> 24 & 0xff + column_2 |>> 16 & 0xff = old column_3 |>> 16 & 0xff + column_2 |>> 8 & 0xff = old column_0 |>> 8 & 0xff + column_2 & 0xff = old column_1 & 0xff + column_3 |>> 24 & 0xff = old column_3 |>> 24 & 0xff + column_3 |>> 16 & 0xff = old column_0 |>> 16 & 0xff + column_3 |>> 8 & 0xff = old column_1 |>> 8 & 0xff + column_3 & 0xff = old column_2 & 0xff + end + + add_round_key (schedule_index: INTEGER) + do + column_0 := column_0.bit_xor (key_schedule [schedule_index]) + column_1 := column_1.bit_xor (key_schedule [schedule_index + 1]) + column_2 := column_2.bit_xor (key_schedule [schedule_index + 2]) + column_3 := column_3.bit_xor (key_schedule [schedule_index + 3]) + end + +feature -- GF(2^8) arithmetic + add (one: INTEGER two: INTEGER): INTEGER + do + result := one.bit_xor (two) + end + + multiply_and_reduce (field: NATURAL_8 multiplier: NATURAL_8): NATURAL_8 + local + field_expanded: NATURAL_32 + do + field_expanded := multiply (field, multiplier) + result := reduce (field_expanded) + end + + multiply (field: NATURAL_8 multiplier: NATURAL_8): NATURAL_32 + local + counter: INTEGER + field_expanded: NATURAL_32 + do + field_expanded := field + from + counter := 0 + until + counter > 7 + loop + if + multiplier.bit_test (counter) + then + result := result.bit_xor (field_expanded.bit_shift_left (counter)) + end + counter := counter + 1 + end + end + + reduce (in: NATURAL_32): NATURAL_8 + local + counter: INTEGER + result_expanded: NATURAL_32 + do + from + counter := 31 + result_expanded := in + until + counter = 7 + loop + if + result_expanded.bit_test (counter) + then + result_expanded := result_expanded.bit_xor (reducer.bit_shift_right (31 - counter)) + end + counter := counter - 1 + end + check + result_expanded <= result.max_value + end + result := result_expanded.to_natural_8 + end + + s_box (in: NATURAL_8): NATURAL_8 + do + result := s [in.to_integer_32] + end + + two_table: SPECIAL [NATURAL_8] + -- Table of {02} * x in GF(2^8) + + three_table: SPECIAL [NATURAL_8] + -- Table of {03} * x in GF(2^8) + + nine_table: SPECIAL [NATURAL_8] + -- Table of {09} * x in GF(2^8) + + eleven_table: SPECIAL [NATURAL_8] + -- Table of {0b} * x in GF(2^8) + + thirteen_table: SPECIAL [NATURAL_8] + -- Table of {0d} * x in GF(2^8) + + fourteen_table: SPECIAL [NATURAL_8] + -- Table of {0E} * x in GF(2^8) + + multiply_table (multiplier: NATURAL_8): SPECIAL [NATURAL_8] + local + counter: INTEGER + do + create result.make_filled (0, 256) + from + counter := 0 + until + counter = 256 + loop + result [counter] := multiply_and_reduce (counter.to_natural_8, multiplier) + counter := counter + 1 + variant + 256 - counter + 1 + end + end + + reducer: NATURAL_32 = 0x8d800000 + +feature {NONE} + byte_sink (in: NATURAL_8) + do + do_nothing + end + + key_schedule: SPECIAL [NATURAL_32] + deferred + end +end diff --git a/library/crypto/eel/aes/aes_key.e b/library/crypto/eel/aes/aes_key.e new file mode 100644 index 00000000..f62cdbf5 --- /dev/null +++ b/library/crypto/eel/aes/aes_key.e @@ -0,0 +1,758 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The single most exciting thing you encounter in government is competence, because it's so rare. - Daniel Patrick Moynihan (1976)" + +class + AES_KEY + +inherit + DEBUG_OUTPUT + ECB_TARGET + rename + encrypt_block as ecb_encrypt, + decrypt_block as ecb_decrypt + end + CBC_TARGET + rename + encrypt_block as cbc_encrypt, + decrypt_block as cbc_decrypt + end + CFB_TARGET + rename + encrypt_block as cfb_encrypt + end + OFB_TARGET + rename + encrypt_block as ofb_encrypt + end + CTR_TARGET + rename + encrypt_block as ctr_encrypt + end + AES_COMMON + AES_ENGINE + +create + make, + make_spec_128, + make_spec_196, + make_spec_256, + make_vector_128, + make_vector_196, + make_vector_256 + +feature -- Key creation + make (key_a: SPECIAL [NATURAL_8]) + require + valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32 + do + make_tables + key := key_a + expand_key_to_schedule (key_a) + end + +feature -- Spec and test vector keys + make_vector_128 + local + vector_key: SPECIAL [NATURAL_8] + do + create vector_key.make_filled (0, 16) + vector_key [0] := 0x00 + vector_key [1] := 0x01 + vector_key [2] := 0x02 + vector_key [3] := 0x03 + vector_key [4] := 0x04 + vector_key [5] := 0x05 + vector_key [6] := 0x06 + vector_key [7] := 0x07 + vector_key [8] := 0x08 + vector_key [9] := 0x09 + vector_key [10] := 0x0a + vector_key [11] := 0x0b + vector_key [12] := 0x0c + vector_key [13] := 0x0d + vector_key [14] := 0x0e + vector_key [15] := 0x0f + make (vector_key) + ensure + vector_128 + end + + make_vector_196 + local + vector_key: SPECIAL [NATURAL_8] + do + create vector_key.make_filled (0, 24) + vector_key [0] := 0x00 + vector_key [1] := 0x01 + vector_key [2] := 0x02 + vector_key [3] := 0x03 + vector_key [4] := 0x04 + vector_key [5] := 0x05 + vector_key [6] := 0x06 + vector_key [7] := 0x07 + vector_key [8] := 0x08 + vector_key [9] := 0x09 + vector_key [10] := 0x0a + vector_key [11] := 0x0b + vector_key [12] := 0x0c + vector_key [13] := 0x0d + vector_key [14] := 0x0e + vector_key [15] := 0x0f + vector_key [16] := 0x10 + vector_key [17] := 0x11 + vector_key [18] := 0x12 + vector_key [19] := 0x13 + vector_key [20] := 0x14 + vector_key [21] := 0x15 + vector_key [22] := 0x16 + vector_key [23] := 0x17 + make (vector_key) + ensure + vector_196 + end + + make_vector_256 + local + vector_key: SPECIAL [NATURAL_8] + do + create vector_key.make_filled (0, 32) + vector_key [0] := 0x00 + vector_key [1] := 0x01 + vector_key [2] := 0x02 + vector_key [3] := 0x03 + vector_key [4] := 0x04 + vector_key [5] := 0x05 + vector_key [6] := 0x06 + vector_key [7] := 0x07 + vector_key [8] := 0x08 + vector_key [9] := 0x09 + vector_key [10] := 0x0a + vector_key [11] := 0x0b + vector_key [12] := 0x0c + vector_key [13] := 0x0d + vector_key [14] := 0x0e + vector_key [15] := 0x0f + vector_key [16] := 0x10 + vector_key [17] := 0x11 + vector_key [18] := 0x12 + vector_key [19] := 0x13 + vector_key [20] := 0x14 + vector_key [21] := 0x15 + vector_key [22] := 0x16 + vector_key [23] := 0x17 + vector_key [24] := 0x18 + vector_key [25] := 0x19 + vector_key [26] := 0x1a + vector_key [27] := 0x1b + vector_key [28] := 0x1c + vector_key [29] := 0x1d + vector_key [30] := 0x1e + vector_key [31] := 0x1f + make (vector_key) + ensure + vector_256 + end + + make_spec_128 + -- Make the FIPS-197 spec 128-bit key + local + spec_key: SPECIAL [NATURAL_8] + do + create spec_key.make_filled (0, 16) + spec_key[0] := 0x2b + spec_key[1] := 0x7e + spec_key[2] := 0x15 + spec_key[3] := 0x16 + spec_key[4] := 0x28 + spec_key[5] := 0xae + spec_key[6] := 0xd2 + spec_key[7] := 0xa6 + spec_key[8] := 0xab + spec_key[9] := 0xf7 + spec_key[10] := 0x15 + spec_key[11] := 0x88 + spec_key[12] := 0x09 + spec_key[13] := 0xcf + spec_key[14] := 0x4f + spec_key[15] := 0x3c + make (spec_key) + ensure + spec_schedule: spec_128 + end + + make_spec_196 + -- Make the FIPS-197 spec 196-bit key + local + spec_key: SPECIAL [NATURAL_8] + do + create spec_key.make_filled (0, 24) + spec_key [0] := 0x8e + spec_key [1] := 0x73 + spec_key [2] := 0xb0 + spec_key [3] := 0xf7 + spec_key [4] := 0xda + spec_key [5] := 0x0e + spec_key [6] := 0x64 + spec_key [7] := 0x52 + spec_key [8] := 0xc8 + spec_key [9] := 0x10 + spec_key [10] := 0xf3 + spec_key [11] := 0x2b + spec_key [12] := 0x80 + spec_key [13] := 0x90 + spec_key [14] := 0x79 + spec_key [15] := 0xe5 + spec_key [16] := 0x62 + spec_key [17] := 0xf8 + spec_key [18] := 0xea + spec_key [19] := 0xd2 + spec_key [20] := 0x52 + spec_key [21] := 0x2c + spec_key [22] := 0x6b + spec_key [23] := 0x7b + make (spec_key) + ensure + spec_schedule: spec_196 + end + + make_spec_256 + -- Make the FIPS-197 spec 256-bit key + local + spec_key: SPECIAL [NATURAL_8] + do + create spec_key.make_filled (0, 32) + spec_key [0] := 0x60 + spec_key [1] := 0x3d + spec_key [2] := 0xeb + spec_key [3] := 0x10 + spec_key [4] := 0x15 + spec_key [5] := 0xca + spec_key [6] := 0x71 + spec_key [7] := 0xbe + spec_key [8] := 0x2b + spec_key [9] := 0x73 + spec_key [10] := 0xae + spec_key [11] := 0xf0 + spec_key [12] := 0x85 + spec_key [13] := 0x7d + spec_key [14] := 0x77 + spec_key [15] := 0x81 + spec_key [16] := 0x1f + spec_key [17] := 0x35 + spec_key [18] := 0x2c + spec_key [19] := 0x07 + spec_key [20] := 0x3b + spec_key [21] := 0x61 + spec_key [22] := 0x08 + spec_key [23] := 0xd7 + spec_key [24] := 0x2d + spec_key [25] := 0x98 + spec_key [26] := 0x10 + spec_key [27] := 0xa3 + spec_key [28] := 0x09 + spec_key [29] := 0x14 + spec_key [30] := 0xdf + spec_key [31] := 0xf4 + make (spec_key) + ensure + spec_schedule: spec_256 + end + +feature {ECB_TARGET} -- ECB + ecb_ready: BOOLEAN + do + result := true + end + + ecb_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + encrypt (in, in_offset, out_array, out_offset) + end + + ecb_decrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + decrypt (in, in_offset, out_array, out_offset) + end + +feature {CBC_TARGET} -- CBC + cbc_ready: BOOLEAN + do + result := true + end + + cbc_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + encrypt (in, in_offset, out_array, out_offset) + end + + cbc_decrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + decrypt (in, in_offset, out_array, out_offset) + end + +feature {CFB_TARGET} -- CFB + cfb_ready: BOOLEAN + do + result := true + end + + cfb_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + encrypt (in, in_offset, out_array, out_offset) + end + +feature {OFB_TARGET} -- OFB + ofb_ready: BOOLEAN + do + result := true + end + + ofb_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + encrypt (in, in_offset, out_array, out_offset) + end + +feature {CTR_TARGET} -- CTR + ctr_ready: BOOLEAN + do + result := true + end + + ctr_encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + do + encrypt (in, in_offset, out_array, out_offset) + end + +feature -- Operations + encrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + require + in.valid_index (in_offset) + out_array.valid_index (out_offset) + in.valid_index (in_offset + 15) + out_array.valid_index (out_offset + 15) + do + unpack (in, in_offset) + encrypt_work (key_schedule.upper) + pack (out_array, out_offset) + end + + decrypt (in: SPECIAL [NATURAL_8] in_offset: INTEGER out_array: SPECIAL [NATURAL_8] out_offset: INTEGER) + require + in.valid_index (in_offset) + out_array.valid_index (out_offset) + in.valid_index (in_offset + 15) + out_array.valid_index (out_offset + 15) + do + unpack (in, in_offset) + decrypt_work (key_schedule.upper) + pack (out_array, out_offset) + end + +feature --Implementation + expand_key_to_schedule (key_a: SPECIAL [NATURAL_8]) + require + valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32 + do + copy_key_to_schedule (key_a) + end + + copy_key_to_schedule (key_a: SPECIAL [NATURAL_8]) + require + valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32 + do + copy_key_to_made_schedule (key_a, 4 * (rounds + 1), key_a.count // 4) + end + + copy_key_to_made_schedule (key_a: SPECIAL [NATURAL_8] schedule_count: INTEGER key_word_count: INTEGER) + require + valid_lengths: key_a.count = 16 or key_a.count = 24 or key_a.count = 32 + local + i: INTEGER + t: INTEGER + sub1, sub2, sub3, sub4: NATURAL_32 + temp: NATURAL_32 + do + create key_schedule.make_filled (0, schedule_count) + from + t := 0 + i := 0 + until + i > key.upper + loop + sub1 := key [i].to_natural_32 |<< 24 + i := i + 1 + sub2 := key [i].to_natural_32 |<< 16 + i := i + 1 + sub3 := key [i].to_natural_32 |<< 8 + i := i + 1 + sub4 := key [i].to_natural_32 + i := i + 1 + key_schedule [t] := sub1 | sub2 | sub3 | sub4 + t := t + 1 + end + from + i := key_a.count.bit_shift_right (2) + until + i >= schedule_count + loop + temp := key_schedule [i - 1] + if + i \\ key_word_count = 0 + then + temp := sub_word (rot_word (temp)).bit_xor (round_constant [i // key_word_count]) + elseif + key_word_count = 8 and i \\ key_word_count = 4 + then + temp := sub_word(temp) + end + key_schedule [i] := key_schedule [i - key_word_count].bit_xor (temp) + i := i + 1 + end + end + + inv_mcol (x: NATURAL_32): NATURAL_32 + local + f2: NATURAL_32 + f4: NATURAL_32 + f8: NATURAL_32 + f9: NATURAL_32 + do + f2 := FFmulX (x) + f4 := FFmulX (f2) + f8 := FFmulX (f4) + f9 := x.bit_xor(f8) + result := f2.bit_xor (f4).bit_xor (f8).bit_xor (rotate_right_32 (f2.bit_xor (f9), 8)).bit_xor (rotate_right_32 (f4.bit_xor (f9), 16)).bit_xor (rotate_right_32 (f9, 24)) + end + + round_constant: SPECIAL [NATURAL_32] + -- rcon + once + create result.make_filled (0, 11) + result [0] := 0x00000000 + result [1] := 0x01000000 + result [2] := 0x02000000 + result [3] := 0x04000000 + result [4] := 0x08000000 + result [5] := 0x10000000 + result [6] := 0x20000000 + result [7] := 0x40000000 + result [8] := 0x80000000 + result [9] := 0x1b000000 + result [10] := 0x36000000 + end + + rounds: INTEGER + require + key.count = 16 or key.count = 24 or key.count = 32 + do + result := key.count.bit_shift_right (2) + 6 + ensure + result = key.count // 4 + 6 + end + + key: SPECIAL [NATURAL_8] + + sub_word (x_a: NATURAL_32): NATURAL_32 + -- S-box word substitution + local + x: INTEGER + do + x := x_a.to_integer_32 + result := result + s [(x |>> 24).bit_and (0xff)] + result := result.bit_shift_left (8) + result := result + s [(x |>> 16).bit_and (0xff)] + result := result.bit_shift_left (8) + result := result + s [(x |>> 8).bit_and (0xff)] + result := result.bit_shift_left (8) + result := result + s [x & 0xff] + end + + rot_word (x: NATURAL_32): NATURAL_32 + -- Rotate left 4 bits + do + result := x.bit_shift_right (24) | x.bit_shift_left (8) + end + + key_schedule: SPECIAL [NATURAL_32] + -- FIPS W + + spec_128_bit_schedule: BOOLEAN + -- Is `key_schedule' the one defined for the 128-bit spec key in FIPS-197 + do + result := key_schedule.count = 44 + result := result and key_schedule [0] = 0x2b7e1516 and key_schedule [1] = 0x28aed2a6 and key_schedule [2] = 0xabf71588 and key_schedule [3] = 0x09cf4f3c + result := result and key_schedule [4] = 0xa0fafe17 and key_schedule [5] = 0x88542cb1 and key_schedule [6] = 0x23a33939 and key_schedule [7] = 0x2a6c7605 + result := result and key_schedule [8] = 0xf2c295f2 and key_schedule [9] = 0x7a96b943 and key_schedule [10] = 0x5935807a and key_schedule [11] = 0x7359f67f + result := result and key_schedule [12] = 0x3d80477d and key_schedule [13] = 0x4716fe3e and key_schedule [14] = 0x1e237e44 and key_schedule [15] = 0x6d7a883b + result := result and key_schedule [16] = 0xef44a541 and key_schedule [17] = 0xa8525b7f and key_schedule [18] = 0xb671253b and key_schedule [19] = 0xdb0bad00 + result := result and key_schedule [20] = 0xd4d1c6f8 and key_schedule [21] = 0x7c839d87 and key_schedule [22] = 0xcaf2b8bc and key_schedule [23] = 0x11f915bc + result := result and key_schedule [24] = 0x6d88a37a and key_schedule [25] = 0x110b3efd and key_schedule [26] = 0xdbf98641 and key_schedule [27] = 0xca0093fd + result := result and key_schedule [28] = 0x4e54f70e and key_schedule [29] = 0x5f5fc9f3 and key_schedule [30] = 0x84a64fb2 and key_schedule [31] = 0x4ea6dc4f + result := result and key_schedule [32] = 0xead27321 and key_schedule [33] = 0xb58dbad2 and key_schedule [34] = 0x312bf560 and key_schedule [35] = 0x7f8d292f + result := result and key_schedule [36] = 0xac7766f3 and key_schedule [37] = 0x19fadc21 and key_schedule [38] = 0x28d12941 and key_schedule [39] = 0x575c006e + result := result and key_schedule [40] = 0xd014f9a8 and key_schedule [41] = 0xc9ee2589 and key_schedule [42] = 0xe13f0cc8 and key_schedule [43] = 0xb6630ca6 + end + + spec_196_bit_schedule: BOOLEAN + -- Is `key_schedule' the one defined for the 196-bit spec key in FIPS-197 + do + result := key_schedule.count = 52 + result := result and key_schedule [0] = 0x8e73b0f7 and key_schedule [1] = 0xda0e6452 and key_schedule [2] = 0xc810f32b and key_schedule [3] = 0x809079e5 + result := result and key_schedule [4] = 0x62f8ead2 and key_schedule [5] = 0x522c6b7b and key_schedule [6] = 0xfe0c91f7 and key_schedule [7] = 0x2402f5a5 + result := result and key_schedule [8] = 0xec12068e and key_schedule [9] = 0x6c827f6b and key_schedule [10] = 0x0e7a95b9 and key_schedule [11] = 0x5c56fec2 + result := result and key_schedule [12] = 0x4db7b4bd and key_schedule [13] = 0x69b54118 and key_schedule [14] = 0x85a74796 and key_schedule [15] = 0xe92538fd + result := result and key_schedule [16] = 0xe75fad44 and key_schedule [17] = 0xbb095386 and key_schedule [18] = 0x485af057 and key_schedule [19] = 0x21efb14f + result := result and key_schedule [20] = 0xa448f6d9 and key_schedule [21] = 0x4d6dce24 and key_schedule [22] = 0xaa326360 and key_schedule [23] = 0x113b30e6 + result := result and key_schedule [24] = 0xa25e7ed5 and key_schedule [25] = 0x83b1cf9a and key_schedule [26] = 0x27f93943 and key_schedule [27] = 0x6a94f767 + result := result and key_schedule [28] = 0xc0a69407 and key_schedule [29] = 0xd19da4e1 and key_schedule [30] = 0xec1786eb and key_schedule [31] = 0x6fa64971 + result := result and key_schedule [32] = 0x485f7032 and key_schedule [33] = 0x22cb8755 and key_schedule [34] = 0xe26d1352 and key_schedule [35] = 0x33f0b7b3 + result := result and key_schedule [36] = 0x40beeb28 and key_schedule [37] = 0x2f18a259 and key_schedule [38] = 0x6747d26b and key_schedule [39] = 0x458c553e + result := result and key_schedule [40] = 0xa7e1466c and key_schedule [41] = 0x9411f1df and key_schedule [42] = 0x821f750a and key_schedule [43] = 0xad07d753 + result := result and key_schedule [44] = 0xca400538 and key_schedule [45] = 0x8fcc5006 and key_schedule [46] = 0x282d166a and key_schedule [47] = 0xbc3ce7b5 + result := result and key_schedule [48] = 0xe98ba06f and key_schedule [49] = 0x448c773c and key_schedule [50] = 0x8ecc7204 and key_schedule [51] = 0x01002202 + end + + spec_256_bit_schedule: BOOLEAN + -- Is `key_schedule' the one defined for the 256-bit spec key in FIPS-197 + do + result := key_schedule.count = 60 + result := result and key_schedule [0] = 0x603deb10 and key_schedule [1] = 0x15ca71be and key_schedule [2] = 0x2b73aef0 and key_schedule [3] = 0x857d7781 + result := result and key_schedule [4] = 0x1f352c07 and key_schedule [5] = 0x3b6108d7 and key_schedule [6] = 0x2d9810a3 and key_schedule [7] = 0x0914dff4 + result := result and key_schedule [8] = 0x9ba35411 and key_schedule [9] = 0x8e6925af and key_schedule [10] = 0xa51a8b5f and key_schedule [11] = 0x2067fcde + result := result and key_schedule [12] = 0xa8b09c1a and key_schedule [13] = 0x93d194cd and key_schedule [14] = 0xbe49846e and key_schedule [15] = 0xb75d5b9a + result := result and key_schedule [16] = 0xd59aecb8 and key_schedule [17] = 0x5bf3c917 and key_schedule [18] = 0xfee94248 and key_schedule [19] = 0xde8ebe96 + result := result and key_schedule [20] = 0xb5a9328a and key_schedule [21] = 0x2678a647 and key_schedule [22] = 0x98312229 and key_schedule [23] = 0x2f6c79b3 + result := result and key_schedule [24] = 0x812c81ad and key_schedule [25] = 0xdadf48ba and key_schedule [26] = 0x24360af2 and key_schedule [27] = 0xfab8b464 + result := result and key_schedule [28] = 0x98c5bfc9 and key_schedule [29] = 0xbebd198e and key_schedule [30] = 0x268c3ba7 and key_schedule [31] = 0x09e04214 + result := result and key_schedule [32] = 0x68007bac and key_schedule [33] = 0xb2df3316 and key_schedule [34] = 0x96e939e4 and key_schedule [35] = 0x6c518d80 + result := result and key_schedule [36] = 0xc814e204 and key_schedule [37] = 0x76a9fb8a and key_schedule [38] = 0x5025c02d and key_schedule [39] = 0x59c58239 + result := result and key_schedule [40] = 0xde136967 and key_schedule [41] = 0x6ccc5a71 and key_schedule [42] = 0xfa256395 and key_schedule [43] = 0x9674ee15 + result := result and key_schedule [44] = 0x5886ca5d and key_schedule [45] = 0x2e2f31d7 and key_schedule [46] = 0x7e0af1fa and key_schedule [47] = 0x27cf73c3 + result := result and key_schedule [48] = 0x749c47ab and key_schedule [49] = 0x18501dda and key_schedule [50] = 0xe2757e4f and key_schedule [51] = 0x7401905a + result := result and key_schedule [52] = 0xcafaaae3 and key_schedule [53] = 0xe4d59b34 and key_schedule [54] = 0x9adf6ace and key_schedule [55] = 0xbd10190d + result := result and key_schedule [56] = 0xfe4890d1 and key_schedule [57] = 0xe6188d0b and key_schedule [58] = 0x046df344 and key_schedule [59] = 0x706c631e + end + + valid_spec_keys: BOOLEAN + local + key128: AES_KEY + key196: AES_KEY + key256: AES_KEY + do + create key128.make_spec_128 + create key196.make_spec_196 + create key256.make_spec_256 + result := key128.spec_128_bit_schedule and key196.spec_196_bit_schedule and key256.spec_256_bit_schedule + end + + valid_spec_keys_once: BOOLEAN + once + result := valid_spec_keys + end + +feature -- Test if the key is a spec key + spec_128: BOOLEAN + do + result := key.count = 16 + result := result and key [0] = 0x2b + result := result and key [1] = 0x7e + result := result and key [2] = 0x15 + result := result and key [3] = 0x16 + result := result and key [4] = 0x28 + result := result and key [5] = 0xae + result := result and key [6] = 0xd2 + result := result and key [7] = 0xa6 + result := result and key [8] = 0xab + result := result and key [9] = 0xf7 + result := result and key [10] = 0x15 + result := result and key [11] = 0x88 + result := result and key [12] = 0x09 + result := result and key [13] = 0xcf + result := result and key [14] = 0x4f + result := result and key [15] = 0x3c + ensure + result implies spec_128_bit_schedule + end + + spec_196: BOOLEAN + do + result := key.count = 24 + result := result and key [0] = 0x8e + result := result and key [1] = 0x73 + result := result and key [2] = 0xb0 + result := result and key [3] = 0xf7 + result := result and key [4] = 0xda + result := result and key [5] = 0x0e + result := result and key [6] = 0x64 + result := result and key [7] = 0x52 + result := result and key [8] = 0xc8 + result := result and key [9] = 0x10 + result := result and key [10] = 0xf3 + result := result and key [11] = 0x2b + result := result and key [12] = 0x80 + result := result and key [13] = 0x90 + result := result and key [14] = 0x79 + result := result and key [15] = 0xe5 + result := result and key [16] = 0x62 + result := result and key [17] = 0xf8 + result := result and key [18] = 0xea + result := result and key [19] = 0xd2 + result := result and key [20] = 0x52 + result := result and key [21] = 0x2c + result := result and key [22] = 0x6b + result := result and key [23] = 0x7b + ensure + result implies spec_196_bit_schedule + end + + spec_256: BOOLEAN + do + result := key.count = 32 + result := result and key [0] = 0x60 + result := result and key [1] = 0x3d + result := result and key [2] = 0xeb + result := result and key [3] = 0x10 + result := result and key [4] = 0x15 + result := result and key [5] = 0xca + result := result and key [6] = 0x71 + result := result and key [7] = 0xbe + result := result and key [8] = 0x2b + result := result and key [9] = 0x73 + result := result and key [10] = 0xae + result := result and key [11] = 0xf0 + result := result and key [12] = 0x85 + result := result and key [13] = 0x7d + result := result and key [14] = 0x77 + result := result and key [15] = 0x81 + result := result and key [16] = 0x1f + result := result and key [17] = 0x35 + result := result and key [18] = 0x2c + result := result and key [19] = 0x07 + result := result and key [20] = 0x3b + result := result and key [21] = 0x61 + result := result and key [22] = 0x08 + result := result and key [23] = 0xd7 + result := result and key [24] = 0x2d + result := result and key [25] = 0x98 + result := result and key [26] = 0x10 + result := result and key [27] = 0xa3 + result := result and key [28] = 0x09 + result := result and key [29] = 0x14 + result := result and key [30] = 0xdf + result := result and key [31] = 0xf4 + ensure + result implies spec_256_bit_schedule + end + + vector_128: BOOLEAN + do + result := key.count = 16 + result := result and key [0] = 0x00 + result := result and key [1] = 0x01 + result := result and key [2] = 0x02 + result := result and key [3] = 0x03 + result := result and key [4] = 0x04 + result := result and key [5] = 0x05 + result := result and key [6] = 0x06 + result := result and key [7] = 0x07 + result := result and key [8] = 0x08 + result := result and key [9] = 0x09 + result := result and key [10] = 0x0a + result := result and key [11] = 0x0b + result := result and key [12] = 0x0c + result := result and key [13] = 0x0d + result := result and key [14] = 0x0e + result := result and key [15] = 0x0f + end + + vector_196: BOOLEAN + do + result := key.count = 24 + result := result and key [0] = 0x00 + result := result and key [1] = 0x01 + result := result and key [2] = 0x02 + result := result and key [3] = 0x03 + result := result and key [4] = 0x04 + result := result and key [5] = 0x05 + result := result and key [6] = 0x06 + result := result and key [7] = 0x07 + result := result and key [8] = 0x08 + result := result and key [9] = 0x09 + result := result and key [10] = 0x0a + result := result and key [11] = 0x0b + result := result and key [12] = 0x0c + result := result and key [13] = 0x0d + result := result and key [14] = 0x0e + result := result and key [15] = 0x0f + result := result and key [16] = 0x10 + result := result and key [17] = 0x11 + result := result and key [18] = 0x12 + result := result and key [19] = 0x13 + result := result and key [20] = 0x14 + result := result and key [21] = 0x15 + result := result and key [22] = 0x16 + result := result and key [23] = 0x17 + end + + vector_256: BOOLEAN + do + result := key.count = 32 + result := result and key [0] = 0x00 + result := result and key [1] = 0x01 + result := result and key [2] = 0x02 + result := result and key [3] = 0x03 + result := result and key [4] = 0x04 + result := result and key [5] = 0x05 + result := result and key [6] = 0x06 + result := result and key [7] = 0x07 + result := result and key [8] = 0x08 + result := result and key [9] = 0x09 + result := result and key [10] = 0x0a + result := result and key [11] = 0x0b + result := result and key [12] = 0x0c + result := result and key [13] = 0x0d + result := result and key [14] = 0x0e + result := result and key [15] = 0x0f + result := result and key [16] = 0x10 + result := result and key [17] = 0x11 + result := result and key [18] = 0x12 + result := result and key [19] = 0x13 + result := result and key [20] = 0x14 + result := result and key [21] = 0x15 + result := result and key [22] = 0x16 + result := result and key [23] = 0x17 + result := result and key [24] = 0x18 + result := result and key [25] = 0x19 + result := result and key [26] = 0x1a + result := result and key [27] = 0x1b + result := result and key [28] = 0x1c + result := result and key [29] = 0x1d + result := result and key [30] = 0x1e + result := result and key [31] = 0x1f + end + +feature -- {DEBUG_OUTPUT} + debug_output: STRING + local + index: INTEGER_32 + do + Result := "0x" + from + index := key.lower + until + index > key.upper + loop + Result.append (key [index].to_hex_string) + index := index + 1 + variant + key.upper - index + 2 + end + end + +invariant + valid_spec_keys_once: valid_spec_keys_once +end diff --git a/library/crypto/eel/array_facilities.e b/library/crypto/eel/array_facilities.e new file mode 100644 index 00000000..9c8e33cb --- /dev/null +++ b/library/crypto/eel/array_facilities.e @@ -0,0 +1,148 @@ +note + description: "Summary description for {ARRAY_FACILITIES}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The human race divides politically into those who want people to be controlled and those who have no such desire. - Robert A. Heinlein" + +deferred class + ARRAY_FACILITIES + +feature {ARRAY_FACILITIES} -- Array manipulation + array_xor (source_1: SPECIAL [NATURAL_8] source_1_offset: INTEGER_32 source_2: SPECIAL [NATURAL_8] source_2_offset: INTEGER_32 destination: SPECIAL [NATURAL_8] destination_offset: INTEGER_32 count: INTEGER_32) + require + source_1.valid_index (source_1_offset) + source_2.valid_index (source_2_offset) + destination.valid_index (destination_offset) + source_1.valid_index (source_1_offset + count - 1) + source_2.valid_index (source_2_offset + count - 1) + destination.valid_index (destination_offset + count - 1) + local + counter: INTEGER_32 + do + from + counter := count + until + counter = 0 + loop + destination [destination_offset + counter - 1] := source_1 [source_1_offset + counter - 1].bit_xor (source_2 [source_2_offset + counter - 1]) + counter := counter - 1 + variant + counter + 1 + end + end + +feature {ARRAY_FACILITIES} -- Big endian NATURAL_32 + from_natural_32_be (source: NATURAL_32 target: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: target.valid_index (offset) + valid_end: target.valid_index (offset + 3) + do + target [offset] := (source |>> 24).to_natural_8 + target [offset + 1] := (source |>> 16).to_natural_8 + target [offset + 2] := (source |>> 8).to_natural_8 + target [offset + 3] := source.to_natural_8 + ensure + byte_0: target [offset] = (source |>> 24).to_natural_8 + byte_1: target [offset + 1] = (source |>> 16).to_natural_8 + byte_2: target [offset + 2] = (source |>> 8).to_natural_8 + byte_3: target [offset + 3] = source.to_natural_8 + end + + as_natural_32_be (source: SPECIAL [NATURAL_8] offset: INTEGER_32): NATURAL_32 + require + valid_start: source.valid_index (offset) + valid_end: source.valid_index (offset + 3) + do + result := source [offset].to_natural_32 |<< 24 + result := result | (source [offset + 1].to_natural_32 |<< 16) + result := result | (source [offset + 2].to_natural_32 |<< 8) + result := result | source [offset + 3].to_natural_32 + ensure + byte_0: source [offset] = (result |>> 24).to_natural_8 + byte_1: source [offset + 1] = (result |>> 16).to_natural_8 + byte_2: source [offset + 2] = (result |>> 8).to_natural_8 + byte_3: source [offset + 3] = result.to_natural_8 + end + + from_natural_32_le (source: NATURAL_32 target: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: target.valid_index (offset) + valid_end: target.valid_index (offset + 3) + do + target [offset] := source.to_natural_8 + target [offset + 1] := (source |>> 8).to_natural_8 + target [offset + 2] := (source |>> 16).to_natural_8 + target [offset + 3] := (source |>> 24).to_natural_8 + ensure + byte_0: target [offset] = source.to_natural_8 + byte_1: target [offset + 1] = (source |>> 8).to_natural_8 + byte_2: target [offset + 2] = (source |>> 16).to_natural_8 + byte_3: target [offset + 3] = (source |>> 24).to_natural_8 + end + + as_natural_32_le (source: SPECIAL [NATURAL_8] offset: INTEGER_32): NATURAL_32 + require + valid_start: source.valid_index (offset) + valid_end: source.valid_index (offset + 3) + do + result := source [offset].to_natural_32 + result := result | (source [offset + 1].to_natural_32 |<< 8) + result := result | (source [offset + 2].to_natural_32 |<< 16) + result := result | (source [offset + 3].to_natural_32 |<< 24) + ensure + byte_0: source [offset] = result.to_natural_8 + byte_1: source [offset + 1] = (result |>> 8).to_natural_8 + byte_2: source [offset + 2] = (result |>> 16).to_natural_8 + byte_3: source [offset + 3] = (result |>> 24).to_natural_8 + end + +feature {ARRAY_FACILITIES} -- Big endian NATURAL_64 + from_natural_64_be (source: NATURAL_64 target: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: target.valid_index (offset) + valid_end: target.valid_index (offset + 7) + do + target [offset] := (source |>> 56).to_natural_8 + target [offset + 1] := (source |>> 48).to_natural_8 + target [offset + 2] := (source |>> 40).to_natural_8 + target [offset + 3] := (source |>> 32).to_natural_8 + target [offset + 4] := (source |>> 24).to_natural_8 + target [offset + 5] := (source |>> 16).to_natural_8 + target [offset + 6] := (source |>> 8).to_natural_8 + target [offset + 7] := source.to_natural_8 + ensure + byte_0: target [offset] = (source |>> 56).to_natural_8 + byte_1: target [offset + 1] = (source |>> 48).to_natural_8 + byte_2: target [offset + 2] = (source |>> 40).to_natural_8 + byte_3: target [offset + 3] = (source |>> 32).to_natural_8 + byte_4: target [offset + 4] = (source |>> 24).to_natural_8 + byte_5: target [offset + 5] = (source |>> 16).to_natural_8 + byte_6: target [offset + 6] = (source |>> 8).to_natural_8 + byte_7: target [offset + 7] = source.to_natural_8 + end + + as_natural_64_be (source: SPECIAL [NATURAL_8] offset: INTEGER_32): NATURAL_64 + require + valid_start: source.valid_index (offset) + valid_end: source.valid_index (offset + 7) + do + result := source [offset].to_natural_32 |<< 56 + result := result | (source [offset + 1].to_natural_32 |<< 48) + result := result | (source [offset + 2].to_natural_32 |<< 40) + result := result | (source [offset + 3].to_natural_32 |<< 32) + result := result | (source [offset + 4].to_natural_32 |<< 24) + result := result | (source [offset + 5].to_natural_32 |<< 16) + result := result | (source [offset + 6].to_natural_32 |<< 8) + result := result | source [offset + 7].to_natural_32 + ensure + byte_0: source [offset] = (result |>> 56).to_natural_8 + byte_1: source [offset + 1] = (result |>> 48).to_natural_8 + byte_2: source [offset + 2] = (result |>> 40).to_natural_8 + byte_3: source [offset + 3] = (result |>> 32).to_natural_8 + byte_4: source [offset + 4] = (result |>> 24).to_natural_8 + byte_5: source [offset + 5] = (result |>> 16).to_natural_8 + byte_6: source [offset + 6] = (result |>> 8).to_natural_8 + byte_7: source [offset + 7] = result.to_natural_8 + end +end diff --git a/library/crypto/eel/byte_32_bit_block_facilities.e b/library/crypto/eel/byte_32_bit_block_facilities.e new file mode 100644 index 00000000..29b86b72 --- /dev/null +++ b/library/crypto/eel/byte_32_bit_block_facilities.e @@ -0,0 +1,56 @@ +note + description: "Facilities to use a stream of bytes as blocks of bytes" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Democracy must be something more than two wolves and a sheep voting on what to have for dinner. - James Bovard (1994)" + +deferred class + BYTE_32_BIT_BLOCK_FACILITIES + +feature + update_word (in: NATURAL_32) + do + update ((in |>> 24).to_natural_8) + update ((in |>> 16).to_natural_8) + update ((in |>> 8).to_natural_8) + update (in.to_natural_8) + ensure + buffer_offset = old buffer_offset + end + + update (in: NATURAL_8) + do + buffer [buffer_offset] := in + buffer_offset := buffer_offset + 1 + if + buffer_offset > buffer.upper + then + process_word (buffer, 0) + buffer_offset := 0 + end + ensure + buffer_offset = (old buffer_offset + 1) \\ bytes + end + + process_word (in: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: in.valid_index (offset) + valid_end: in.valid_index (offset + bytes - 1) + deferred + end + + bytes: INTEGER + do + Result := 4 + end + +feature {NONE} + buffer: SPECIAL [NATURAL_8] + buffer_offset: INTEGER_32 + +invariant + buffer_lower: buffer.lower = 0 + buffer_upper: buffer.upper = buffer.lower + bytes - 1 + valid_buffer_offset: buffer.valid_index (buffer_offset) +end diff --git a/library/crypto/eel/byte_64_bit_block_facilities.e b/library/crypto/eel/byte_64_bit_block_facilities.e new file mode 100644 index 00000000..afee4019 --- /dev/null +++ b/library/crypto/eel/byte_64_bit_block_facilities.e @@ -0,0 +1,19 @@ +note + description: "Summary description for {BYTE_64_BIT_BLOCK_FACILITIES}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The evils of tyranny are rarely seen but by him who resists it. - John Hay (1872)" + +deferred class + BYTE_64_BIT_BLOCK_FACILITIES + +inherit + BYTE_32_BIT_BLOCK_FACILITIES + redefine + bytes + end + +feature + bytes: INTEGER = 8 +end diff --git a/library/crypto/eel/byte_facilities.e b/library/crypto/eel/byte_facilities.e new file mode 100644 index 00000000..3f633e6f --- /dev/null +++ b/library/crypto/eel/byte_facilities.e @@ -0,0 +1,85 @@ +note + description: "Summary description for {ARRAY_FACILITIES}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The triumph of persuasion over force is the sign of a civilized society. - Mark Skousen" + +deferred class + BYTE_FACILITIES + +inherit + ARRAY_FACILITIES + +feature -- Byte sinks + sink_special (in: SPECIAL [NATURAL_8] in_lower: INTEGER_32 in_upper: INTEGER_32) + require + in.valid_index (in_lower) + in.valid_index (in_upper) + local + index: INTEGER_32 + do + from + index := in_upper + until + index < in_lower + loop + byte_sink (in [index]) + index := index - 1 + variant + index + end + end + + sink_special_lsb (in: SPECIAL [NATURAL_8]; in_lower: INTEGER_32; in_upper: INTEGER_32) + require + in.valid_index (in_lower) + in.valid_index (in_upper) + local + index: INTEGER_32 + do + from + index := in_lower + until + index > in_upper + loop + byte_sink (in [index]) + index := index + 1 + variant + in_upper - index + 2 + end + end + + sink_character (in: CHARACTER_8) + do + byte_sink (in.code.to_natural_8) + end + + sink_natural_32_be (in: NATURAL_32) + do + byte_sink ((in |>> 24).to_natural_8) + byte_sink ((in |>> 16).to_natural_8) + byte_sink ((in |>> 8).to_natural_8) + byte_sink (in.to_natural_8) + end + + sink_string (in: STRING) + local + i: INTEGER + do + from + i := 1 + until + i > in.count + loop + sink_character (in.item (i)) + i := i + 1 + variant + in.area.upper - i + 1 + end + end + + byte_sink (in: NATURAL_8) + deferred + end +end diff --git a/library/crypto/eel/constants.e b/library/crypto/eel/constants.e new file mode 100644 index 00000000..962019f1 --- /dev/null +++ b/library/crypto/eel/constants.e @@ -0,0 +1,36 @@ +note + description: "Facilities for INTEGER_X constants" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "There is no worse tyranny than to force a man to pay for what he does not want merely because you think it would be good for him. - Robert Heinlein " + +deferred class + CONSTANTS + +feature + four: INTEGER_X + do + create result.make_from_integer(4) + end + + three: INTEGER_X + do + create result.make_from_integer(3) + end + + two: INTEGER_X + do + create result.make_from_integer(2) + end + + one: INTEGER_X + do + create result.make_from_integer(1) + end + + zero: INTEGER_X + do + create result.default_create + end +end diff --git a/library/crypto/eel/der/array_der_sink.e b/library/crypto/eel/der/array_der_sink.e new file mode 100644 index 00000000..9c5dde8c --- /dev/null +++ b/library/crypto/eel/der/array_der_sink.e @@ -0,0 +1,29 @@ +note + description: "Summary description for {ARRAY_DER_SINK}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + ARRAY_DER_SINK + +inherit + DER_OCTET_SINK + +create + make + +feature + make (target_a: ARRAY [NATURAL_8]) + do + target := target_a + end + + sink (item: NATURAL_8) + do + target.force (item, target.upper + 1) + end + +feature {NONE} + target: ARRAY [NATURAL_8] +end diff --git a/library/crypto/eel/der/array_der_source.e b/library/crypto/eel/der/array_der_source.e new file mode 100644 index 00000000..3599971a --- /dev/null +++ b/library/crypto/eel/der/array_der_source.e @@ -0,0 +1,44 @@ +note + description: "Summary description for {ARRAY_DER_SOURCE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + ARRAY_DER_SOURCE + +inherit + DER_OCTET_SOURCE + +create + make + +feature + make (source_a: ARRAY [NATURAL_8]) + do + source := source_a + end + +feature + has_item: BOOLEAN + do + result := source.valid_index (current_index) + end + + item: NATURAL_8 + do + result := source [current_index] + end + + process + do + current_index := current_index + 1 + end + +feature {NONE} + current_index: INTEGER_32 + source: ARRAY [NATURAL_8] + +invariant + source.valid_index (current_index) or current_index = source.upper + 1 +end diff --git a/library/crypto/eel/der/der_encodable.e b/library/crypto/eel/der/der_encodable.e new file mode 100644 index 00000000..6ee6a514 --- /dev/null +++ b/library/crypto/eel/der/der_encodable.e @@ -0,0 +1,18 @@ +note + description: "An object that is DER encodable" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "I think the terror most people are concerned with is the IRS. - Malcolm Forbes, when asked if he was afraid of terrorism" + +deferred class + DER_ENCODABLE + +inherit + DER_FACILITIES + +feature + der_encode (target: DER_OCTET_SINK) + deferred + end +end diff --git a/library/crypto/eel/der/der_encoding.e b/library/crypto/eel/der/der_encoding.e new file mode 100644 index 00000000..95c99fa8 --- /dev/null +++ b/library/crypto/eel/der/der_encoding.e @@ -0,0 +1,24 @@ +note + description: "Summary description for {DER_ENCODING}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + DER_ENCODING + +inherit + DEVELOPER_EXCEPTION + +create + make + +feature + make (reason_a: STRING) + do + reason := reason_a + end + +feature + reason: STRING +end diff --git a/library/crypto/eel/der/der_facilities.e b/library/crypto/eel/der/der_facilities.e new file mode 100644 index 00000000..491a04dd --- /dev/null +++ b/library/crypto/eel/der/der_facilities.e @@ -0,0 +1,196 @@ +note + description: "Summary description for {DER_FACILITIES}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + +deferred class + DER_FACILITIES + +inherit + DER_UNIVERSAL_CLASS_TAG + +feature + identifier_class (in: NATURAL_8): NATURAL_8 + do + result := in & 0xc0 + end + + identifier_universal: NATURAL_8 = 0x00 + identifier_application: NATURAL_8 = 0xa0 + identifier_context_specific: NATURAL_8 = 0xb0 + identifier_private: NATURAL_8 = 0xc0 + identifier_constructed: NATURAL_8 = 0x20 + + identifier_primitive (in: NATURAL_8): BOOLEAN + do + result := (in & identifier_constructed) = 0 + end + + identifier_tag (in: NATURAL_8): NATURAL_8 + do + result := in & 0x1f + end + + identifier_high_number (in: NATURAL_8): BOOLEAN + do + result := identifier_tag (in) = 0x1f + end + + identifier_last (in: NATURAL_8): BOOLEAN + do + result := (in & 0x80) = 0 + end + + encode_boolean (target: DER_OCTET_SINK in: BOOLEAN) + do + target.sink (boolean) + target.sink (0x01) + if + in + then + target.sink (0xff) + else + target.sink (0x00) + end + end + + definite_length (target: DER_OCTET_SINK length: INTEGER_32) + require + length >= 0 + do + if + length <= 127 + then + definite_short_length (target, length) + else + definite_long_length (target, length) + end + end + + definite_short_length (target: DER_OCTET_SINK length: INTEGER_32) + require + length >= 0 + length <= 127 + do + target.sink (length.to_natural_8) + end + + definite_long_length (target: DER_OCTET_SINK length: INTEGER_32) + require + length >= 0 + do + target.sink (0x84) + target.sink ((length |>> 24).to_natural_8) + target.sink ((length |>> 16).to_natural_8) + target.sink ((length |>> 8).to_natural_8) + target.sink ((length |>> 0).to_natural_8) + end + + + decode_length (source: DER_OCTET_SOURCE): INTEGER_X + do + if + source.item <= 127 + then + result := decode_short_length (source) + else + result := decode_long_length (source) + end + end + + decode_short_length (source: DER_OCTET_SOURCE): INTEGER_X + do + create result.make_from_integer (source.item.to_integer_32) + source.process + end + + decode_long_length (source: DER_OCTET_SOURCE): INTEGER_X + local + length_count: INTEGER_32 + current_byte: INTEGER_32 + current_bit: INTEGER_32 + do + length_count := (source.item & 0x7f).to_integer_32 + if + length_count = 127 + then + (create {DER_ENCODING}.make ("Unacceptable long form length encoding")).raise + end + create result.default_create + from + current_byte := length_count + until + current_byte = 0 + loop + from + current_bit := 8 + until + current_bit = 0 + loop + if + source.item.bit_test (current_bit - 1) + then + Result := Result.set_bit_value (True, (current_byte - 1) * 8 + (current_bit - 1)) + end + current_bit := current_bit - 1 + variant + current_bit + 1 + end + source.process + current_byte := current_byte - 1 + variant + current_byte + 1 + end + end + + encode_integer (target: DER_OCTET_SINK in: INTEGER_X) + local + bytes: INTEGER_32 + counter: INTEGER_32 + do + if + in.is_negative + then + bytes := (in + in.one).bytes + else + bytes := in.bytes + end + target.sink (integer) + definite_length (target, bytes) + from + counter := bytes + until + counter = 0 + loop + target.sink (byte_at (in, counter)) + counter := counter - 1 + variant + counter + 1 + end + end + + byte_at (in: INTEGER_X index: INTEGER_32): NATURAL_8 + require + index >= 0 + index <= in.bytes + local + current_bit: INTEGER_32 + do + from + current_bit := 8 + until + current_bit = 0 + loop + result := result |<< 1 + if + in.bit_test ((index - 1) * 8 + (current_bit - 1)) + then + result := result | 0x01 + end + current_bit := current_bit - 1 + variant + current_bit + 1 + end + end +end diff --git a/library/crypto/eel/der/der_octet_sink.e b/library/crypto/eel/der/der_octet_sink.e new file mode 100644 index 00000000..b70ed564 --- /dev/null +++ b/library/crypto/eel/der/der_octet_sink.e @@ -0,0 +1,15 @@ +note + description: "A sink for DER octets" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The illegal we do immediately. The unconstitutional takes a bit longer. - Henry Kissinger" + +deferred class + DER_OCTET_SINK + +feature + sink (item: NATURAL_8) + deferred + end +end diff --git a/library/crypto/eel/der/der_octet_source.e b/library/crypto/eel/der/der_octet_source.e new file mode 100644 index 00000000..b573e07e --- /dev/null +++ b/library/crypto/eel/der/der_octet_source.e @@ -0,0 +1,27 @@ +note + description: "DER octet source" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Our forefathers made one mistake. What they should have fought for was representation without taxation. - Fletcher Knebel, historian" + +deferred class + DER_OCTET_SOURCE + +feature + has_item: BOOLEAN + deferred + end + + item: NATURAL_8 + require + has_item + deferred + end + + process + require + has_item + deferred + end +end diff --git a/library/crypto/eel/der/der_universal_class_tag.e b/library/crypto/eel/der/der_universal_class_tag.e new file mode 100644 index 00000000..e4df798d --- /dev/null +++ b/library/crypto/eel/der/der_universal_class_tag.e @@ -0,0 +1,31 @@ +note + description: "ASN.1 universal class tag assignments X.680 8.4" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The usual road to slavery is that first they take away your guns, then they take away your property, then last of all they tell you to shut up and say you are enjoying it. - James A. Donald" + +deferred class + DER_UNIVERSAL_CLASS_TAG + +feature + reserved: NATURAL_8 = 0x0 + boolean: NATURAL_8 = 0x1 + integer: NATURAL_8 = 0x2 + bit_string: NATURAL_8 = 0x3 + octet_string: NATURAL_8 = 0x4 + null: NATURAL_8 = 0x5 + object_identifier: NATURAL_8 = 0x6 + object_descriptor: NATURAL_8 = 0x7 + external_type: NATURAL_8 = 0x8 + real: NATURAL_8 = 0x9 + enumerated: NATURAL_8 = 0xa + embedded_pdv: NATURAL_8 = 0xb + utf8_string: NATURAL_8 = 0xc + relative_object_identifier: NATURAL_8 = 0xd + sequence: NATURAL_8 = 0x10 + set: NATURAL_8 = 0x11 + universal_time: NATURAL_8 = 0x17 + generalized_time: NATURAL_8 = 0x18 + +end diff --git a/library/crypto/eel/digests/MD5/md5.e b/library/crypto/eel/digests/MD5/md5.e new file mode 100644 index 00000000..ef2829d8 --- /dev/null +++ b/library/crypto/eel/digests/MD5/md5.e @@ -0,0 +1,283 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Blessed are the young, for they shall inherit the national debt. - Herbert Hoover" + +class + MD5 + +inherit + ANY + redefine + is_equal + end + SHA_FUNCTIONS + rename + ch as f, + parity as h, + byte_sink as update + export + {MD5} + schedule, + buffer, + byte_count, + schedule_offset, + buffer_offset + undefine + is_equal + redefine + process_length, + process_word, + update_word + end + ROTATE_FACILITIES + undefine + is_equal + end + DEBUG_OUTPUT + undefine + is_equal + end + +create + make, + make_copy + +feature + make + do + create schedule.make_filled (0, 16) + create buffer.make_filled (0, 4) + reset + end + + make_copy (other: like Current) + do + make + schedule.copy_data (other.schedule, other.schedule.lower, schedule.lower, schedule.count) + buffer.copy_data (other.buffer, other.buffer.lower, buffer.lower, buffer.count) + h1 := other.h1 + h2 := other.h2 + h3 := other.h3 + h4 := other.h4 + schedule_offset := other.schedule_offset + byte_count := other.byte_count + buffer_offset := other.buffer_offset + ensure + Current ~ other + end + +feature + reset + do + byte_count := 0 + schedule_offset := 0 + buffer_offset := 0 + h1 := 0x67452301 + h2 := 0xefcdab89 + h3 := 0x98badcfe + h4 := 0x10325476 + ensure + byte_count = 0 + schedule_offset = 0 + buffer_offset = 0 + h1 = 0x67452301 + h2 = 0xefcdab89 + h3 = 0x98badcfe + h4 = 0x10325476 + end + + do_final (output: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: output.valid_index (offset) + valid_end: output.valid_index (offset + 15) + do + finish + from_natural_32_le (h1, output, offset) + from_natural_32_le (h2, output, offset + 4) + from_natural_32_le (h3, output, offset + 8) + from_natural_32_le (h4, output, offset + 12) + reset + end + + current_final (output: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: output.valid_index (offset) + valid_end: output.valid_index (offset + 15) + local + current_copy: like Current + do + create current_copy.make_copy (Current) + current_copy.do_final (output, offset) + end + + current_out: STRING + local + output: SPECIAL [NATURAL_8] + index: INTEGER_32 + do + Result := "0x" + create output.make_filled (0, 16) + current_final (output, 0) + from + index := 0 + until + index = 16 + loop + Result.append (output [index].to_hex_string) + index := index + 1 + end + end + + is_equal (other: like Current): BOOLEAN + do + Result := + schedule.same_items (other.schedule, other.schedule.lower, schedule.lower, schedule.count) and + buffer.same_items (other.buffer, other.buffer.lower, buffer.lower, buffer.count) and + h1 = other.h1 and + h2 = other.h2 and + h3 = other.h3 and + h4 = other.h4 and + schedule_offset = other.schedule_offset and + byte_count = other.byte_count and + buffer_offset = other.buffer_offset + end + +feature {NONE} + g (u: NATURAL_32 v: NATURAL_32 w: NATURAL_32): NATURAL_32 + do + result := (u & w) | (v & w.bit_not) + end + + k (u: NATURAL_32 v: NATURAL_32 w: NATURAL_32): NATURAL_32 + do + result := v.bit_xor (u | w.bit_not) + end + + process_length (length: NATURAL_64) + do + update_word (length.to_natural_32) + update_word ((length |>> 32).to_natural_32) + end + +feature {NONE} + process_word (in: SPECIAL [NATURAL_8] offset: INTEGER_32) + do + schedule [schedule_offset] := as_natural_32_le (in, offset) + schedule_offset := schedule_offset + 1 + if + schedule_offset = 16 + then + schedule_offset := 0 + process_block + end + end + + update_word (in: NATURAL_32) + do + update (in.to_natural_8) + update ((in |>> 8).to_natural_8) + update ((in |>> 16).to_natural_8) + update ((in |>> 24).to_natural_8) + end + + process_block + do + a := h1 + b := h2 + c := h3 + d := h4 + + a := rotate_left_32 (a + f (b, c, d) + schedule [0] + 0xd76aa478, 7) + b + d := rotate_left_32 (d + f (a, b, c) + schedule [1] + 0xe8c7b756, 12) + a + c := rotate_left_32 (c + f (d, a, b) + schedule [2] + 0x242070db, 17) + d + b := rotate_left_32 (b + f (c, d, a) + schedule [3] + 0xc1bdceee, 22) + c + a := rotate_left_32 (a + f (b, c, d) + schedule [4] + 0xf57c0faf, 7) + b + d := rotate_left_32 (d + f (a, b, c) + schedule [5] + 0x4787c62a, 12) + a + c := rotate_left_32 (c + f (d, a, b) + schedule [6] + 0xa8304613, 17) + d + b := rotate_left_32 (b + f (c, d, a) + schedule [7] + 0xfd469501, 22) + c + a := rotate_left_32 (a + f (b, c, d) + schedule [8] + 0x698098d8, 7) + b + d := rotate_left_32 (d + f (a, b, c) + schedule [9] + 0x8b44f7af, 12) + a + c := rotate_left_32 (c + f (d, a, b) + schedule [10] + 0xffff5bb1, 17) + d + b := rotate_left_32 (b + f (c, d, a) + schedule [11] + 0x895cd7be, 22) + c + a := rotate_left_32 (a + f (b, c, d) + schedule [12] + 0x6b901122, 7) + b + d := rotate_left_32 (d + f (a, b, c) + schedule [13] + 0xfd987193, 12) + a + c := rotate_left_32 (c + f (d, a, b) + schedule [14] + 0xa679438e, 17) + d + b := rotate_left_32 (b + f (c, d, a) + schedule [15] + 0x49b40821, 22) + c + + a := rotate_left_32 (a + g (b, c, d) + schedule [1] + 0xf61e2562, 5) + b + d := rotate_left_32 (d + g (a, b, c) + schedule [6] + 0xc040b340, 9) + a + c := rotate_left_32 (c + g (d, a, b) + schedule [11] + 0x265e5a51, 14) + d + b := rotate_left_32 (b + g (c, d, a) + schedule [0] + 0xe9b6c7aa, 20) + c + a := rotate_left_32 (a + g (b, c, d) + schedule [5] + 0xd62f105d, 5) + b + d := rotate_left_32 (d + g (a, b, c) + schedule [10] + 0x02441453, 9) + a + c := rotate_left_32 (c + g (d, a, b) + schedule [15] + 0xd8a1e681, 14) + d + b := rotate_left_32 (b + g (c, d, a) + schedule [4] + 0xe7d3fbc8, 20) + c + a := rotate_left_32 (a + g (b, c, d) + schedule [9] + 0x21e1cde6, 5) + b + d := rotate_left_32 (d + g (a, b, c) + schedule [14] + 0xc33707d6, 9) + a + c := rotate_left_32 (c + g (d, a, b) + schedule [3] + 0xf4d50d87, 14) + d + b := rotate_left_32 (b + g (c, d, a) + schedule [8] + 0x455a14ed, 20) + c + a := rotate_left_32 (a + g (b, c, d) + schedule [13] + 0xa9e3e905, 5) + b + d := rotate_left_32 (d + g (a, b, c) + schedule [2] + 0xfcefa3f8, 9) + a + c := rotate_left_32 (c + g (d, a, b) + schedule [7] + 0x676f02d9, 14) + d + b := rotate_left_32 (b + g (c, d, a) + schedule [12] + 0x8d2a4c8a, 20) + c + + a := rotate_left_32 (a + h (b, c, d) + schedule [5] + 0xfffa3942, 4) + b + d := rotate_left_32 (d + h (a, b, c) + schedule [8] + 0x8771f681, 11) + a + c := rotate_left_32 (c + h (d, a, b) + schedule [11] + 0x6d9d6122, 16) + d + b := rotate_left_32 (b + h (c, d, a) + schedule [14] + 0xfde5380c, 23) + c + a := rotate_left_32 (a + h (b, c, d) + schedule [1] + 0xa4beea44, 4) + b + d := rotate_left_32 (d + h (a, b, c) + schedule [4] + 0x4bdecfa9, 11) + a + c := rotate_left_32 (c + h (d, a, b) + schedule [7] + 0xf6bb4b60, 16) + d + b := rotate_left_32 (b + h (c, d, a) + schedule [10] + 0xbebfbc70, 23) + c + a := rotate_left_32 (a + h (b, c, d) + schedule [13] + 0x289b7ec6, 4) + b + d := rotate_left_32 (d + h (a, b, c) + schedule [0] + 0xeaa127fa, 11) + a + c := rotate_left_32 (c + h (d, a, b) + schedule [3] + 0xd4ef3085, 16) + d + b := rotate_left_32 (b + h (c, d, a) + schedule [6] + 0x04881d05, 23) + c + a := rotate_left_32 (a + h (b, c, d) + schedule [9] + 0xd9d4d039, 4) + b + d := rotate_left_32 (d + h (a, b, c) + schedule [12] + 0xe6db99e5, 11) + a + c := rotate_left_32 (c + h (d, a, b) + schedule [15] + 0x1fa27cf8, 16) + d + b := rotate_left_32 (b + h (c, d, a) + schedule [2] + 0xc4ac5665, 23) + c + + a := rotate_left_32 (a + k (b, c, d) + schedule [0] + 0xf4292244, 6) + b + d := rotate_left_32 (d + k (a, b, c) + schedule [7] + 0x432aff97, 10) + a + c := rotate_left_32 (c + k (d, a, b) + schedule [14] + 0xab9423a7, 15) + d + b := rotate_left_32 (b + k (c, d, a) + schedule [5] + 0xfc93a039, 21) + c + a := rotate_left_32 (a + k (b, c, d) + schedule [12] + 0x655b59c3, 6) + b + d := rotate_left_32 (d + k (a, b, c) + schedule [3] + 0x8f0ccc92, 10) + a + c := rotate_left_32 (c + k (d, a, b) + schedule [10] + 0xffeff47d, 15) + d + b := rotate_left_32 (b + k (c, d, a) + schedule [1] + 0x85845dd1, 21) + c + a := rotate_left_32 (a + k (b, c, d) + schedule [8] + 0x6fa87e4f, 6) + b + d := rotate_left_32 (d + k (a, b, c) + schedule [15] + 0xfe2ce6e0, 10) + a + c := rotate_left_32 (c + k (d, a, b) + schedule [6] + 0xa3014314, 15) + d + b := rotate_left_32 (b + k (c, d, a) + schedule [13] + 0x4e0811a1, 21) + c + a := rotate_left_32 (a + k (b, c, d) + schedule [4] + 0xf7537e82, 6) + b + d := rotate_left_32 (d + k (a, b, c) + schedule [11] + 0xbd3af235, 10) + a + c := rotate_left_32 (c + k (d, a, b) + schedule [2] + 0x2ad7d2bb, 15) + d + b := rotate_left_32 (b + k (c, d, a) + schedule [9] + 0xeb86d391, 21) + c + + h1 := h1 + a + h2 := h2 + b + h3 := h3 + c + h4 := h4 + d + end + + a: NATURAL_32 + b: NATURAL_32 + c: NATURAL_32 + d: NATURAL_32 + +feature -- {DEBUG_OUTPUT} + debug_output: STRING + do + Result := current_out + end + +feature {MD5} + h1: NATURAL_32 + h2: NATURAL_32 + h3: NATURAL_32 + h4: NATURAL_32 +end diff --git a/library/crypto/eel/digests/SHA1/sha1.e b/library/crypto/eel/digests/SHA1/sha1.e new file mode 100644 index 00000000..f473bb33 --- /dev/null +++ b/library/crypto/eel/digests/SHA1/sha1.e @@ -0,0 +1,346 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "There's never been a good government. - Emma Goldman" + +class + SHA1 + +inherit + ANY + redefine + is_equal + end + DEBUG_OUTPUT + undefine + is_equal + end + SHA_FUNCTIONS + rename + byte_sink as update + export + {SHA1} + schedule, + buffer, + byte_count, + schedule_offset, + buffer_offset + undefine + is_equal + end + ROTATE_FACILITIES + undefine + is_equal + end + +create + make, + make_copy + +feature -- Creation + make + do + create schedule.make_filled (0, 80) + create buffer.make_filled (0, 4) + buffer_offset := 0 + reset + end + + make_copy (other: like Current) + do + make + schedule.copy_data (other.schedule, other.schedule.lower, schedule.lower, schedule.count) + buffer.copy_data (other.buffer, other.buffer.lower, buffer.lower, buffer.count) + byte_count := other.byte_count + buffer_offset := other.buffer_offset + h1 := other.h1 + h2 := other.h2 + h3 := other.h3 + h4 := other.h4 + h5 := other.h5 + schedule_offset := other.schedule_offset + ensure + Current ~ other + end + +feature -- Implementing DIGEST + reset + do + byte_count := 0 + buffer_offset := 0 + h1 := 0x67452301 + h2 := 0xefcdab89 + h3 := 0x98badcfe + h4 := 0x10325476 + h5 := 0xc3d2e1f0 + schedule_offset := 0 + ensure + byte_count = 0 + buffer_offset = 0 + schedule_offset = 0 + h1 = 0x67452301 + h2 = 0xefcdab89 + h3 = 0x98badcfe + h4 = 0x10325476 + h5 = 0xc3d2e1f0 + end + + do_final (output: SPECIAL [NATURAL_8] offset: INTEGER) + require + valid_start: output.valid_index (offset) + valid_end: output.valid_index (offset + 19) + do + finish + + unpack_word (h1, output, offset) + unpack_word (h2, output, offset + 4) + unpack_word (h3, output, offset + 8) + unpack_word (h4, output, offset + 12) + unpack_word (h5, output, offset + 16) + + reset + end + + current_final (output: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: output.valid_index (offset) + valid_end: output.valid_index (offset + 19) + local + current_copy: like Current + do + current_copy := Current.deep_twin + current_copy.do_final (output, offset) + end + + current_out: STRING + local + output: SPECIAL [NATURAL_8] + index: INTEGER_32 + do + Result := "0x" + create output.make_filled (0, 20) + current_final (output, 0) + from + index := 0 + until + index = 20 + loop + Result.append (output [index].to_hex_string) + index := index + 1 + end + end + + is_equal (other: like Current): BOOLEAN + do + Result := + schedule.same_items (other.schedule, other.schedule.lower, schedule.lower, schedule.count) and + buffer.same_items (other.buffer, other.buffer.lower, buffer.lower, buffer.count) and + h1 = other.h1 and + h2 = other.h2 and + h3 = other.h3 and + h4 = other.h4 and + h5 = other.h5 and + schedule_offset = other.schedule_offset and + byte_count = other.byte_count and + buffer_offset = other.buffer_offset + end + +feature {NONE} + unpack_word (word: NATURAL_32 output: SPECIAL [NATURAL_8] offset: INTEGER) + require + valid_start: output.valid_index (offset) + valid_end: output.valid_index (offset + 3) + do + output [offset] := (word |>> 24).to_natural_8 + output [offset + 1] := (word |>> 16).to_natural_8 + output [offset + 2] := (word |>> 8).to_natural_8 + output [offset + 3] := word.to_natural_8 + end + + A: NATURAL_32 + B: NATURAL_32 + C: NATURAL_32 + D: NATURAL_32 + E: NATURAL_32 + + process_block + do + expand_word_block + A := H1 + B := H2 + C := H3 + D := H4 + E := H5 + do_round_1 + do_round_2 + do_round_3 + do_round_4 + h1 := h1 + a + h2 := h2 + b + h3 := h3 + c + h4 := h4 + d + h5 := h5 + e + end + + do_round_4 + local + j: INTEGER + idx: INTEGER + do + idx := 60 + from + j := 0 + until + j = 4 + loop + e := e + rotate_left_32 (a, 5) + parity (b, c, d) + schedule [idx] + k4 + idx := idx + 1 + b := rotate_left_32 (b, 30) + d := d + rotate_left_32 (e, 5) + parity (a, b, c) + schedule [idx] + k4 + idx := idx + 1 + a := rotate_left_32 (a, 30) + c := c + rotate_left_32 (d, 5) + parity (e, a, b) + schedule [idx] + k4 + idx := idx + 1 + e := rotate_left_32 (e, 30) + b := b + rotate_left_32 (c, 5) + parity (d, e, a) + schedule [idx] + k4 + idx := idx + 1 + d := rotate_left_32 (d, 30) + a := a + rotate_left_32 (b, 5) + parity (c, d, e) + schedule [idx] + k4 + idx := idx + 1 + c := rotate_left_32 (c, 30) + j := j + 1 + end + end + + do_round_3 + local + j: INTEGER + idx: INTEGER + do + idx := 40 + from + j := 0 + until + j = 4 + loop + E := E + rotate_left_32 (a, 5) + maj (B, C, D) + schedule [idx] + k3 + idx := idx + 1 + B := rotate_left_32 (b, 30) + D := d + rotate_left_32 (e, 5) + maj (a, b, c) + schedule [idx] + k3 + idx := idx + 1 + A := rotate_left_32 (a, 30) + C := C + rotate_left_32 (d, 5) + maj (e, a, b) + schedule [idx] + k3 + idx := idx + 1 + e := rotate_left_32 (e, 30) + b := b + rotate_left_32 (c, 5) + maj (d, e, a) + schedule [idx] + k3 + idx := idx + 1 + d := rotate_left_32 (d, 30) + a := a + rotate_left_32 (b, 5) + maj (c, d, e) + schedule [idx] + k3 + idx := idx + 1 + c := rotate_left_32 (c, 30) + j := j + 1 + end + end + + do_round_2 + local + j: INTEGER + idx: INTEGER + do + idx := 20 + from + j := 0 + until + j = 4 + loop + E := E + rotate_left_32 (a, 5) + parity(B, C, D) + schedule [idx] + k2 + idx := idx + 1 + B := rotate_left_32 (b, 30) + D := d + rotate_left_32 (e, 5) + parity(a, b, c) + schedule [idx] + k2 + idx := idx + 1 + A := rotate_left_32 (a, 30) + C := C + rotate_left_32 (d, 5) + parity(e, a, b) + schedule [idx] + k2 + idx := idx + 1 + e := rotate_left_32 (e, 30) + b := b + rotate_left_32 (c, 5) + parity(d, e, a) + schedule [idx] + k2 + idx := idx + 1 + d := rotate_left_32 (d, 30) + a := a + rotate_left_32 (b, 5) + parity(c, d, e) + schedule [idx] + k2 + idx := idx + 1 + c := rotate_left_32 (c, 30) + j := j + 1 + end + end + + do_round_1 + local + j: INTEGER + idx: INTEGER + do + idx := 0 + from + j := 0 + until + j = 4 + loop + E := E + rotate_left_32 (a, 5) + ch (B, C, D) + schedule [idx] + k1 + idx := idx + 1 + B := rotate_left_32 (b, 30) + D := d + rotate_left_32 (e, 5) + ch (a, b, c) + schedule [idx] + k1 + idx := idx + 1 + A := rotate_left_32 (a, 30) + C := C + rotate_left_32 (d, 5) + ch (e, a, b) + schedule [idx] + k1 + idx := idx + 1 + e := rotate_left_32 (e, 30) + b := b + rotate_left_32 (c, 5) + ch (d, e, a) + schedule [idx] + k1 + idx := idx + 1 + d := rotate_left_32 (d, 30) + a := a + rotate_left_32 (b, 5) + ch (c, d, e) + schedule [idx] + k1 + idx := idx + 1 + c := rotate_left_32 (c, 30) + j := j + 1 + end + end + + expand_word_block + -- Expand 16 word block in to 80 word block + local + i: INTEGER + temp: NATURAL_32 + do + from + i := 16 + until + i = 80 + loop + temp := schedule [i - 3].bit_xor (schedule [i - 8]).bit_xor (schedule [i - 14]).bit_xor (schedule [i - 16]) + schedule [i] := rotate_left_32 (temp, 1) + i := i + 1 + end + end + +feature {SHA1} + H1: NATURAL_32 + H2: NATURAL_32 + H3: NATURAL_32 + H4: NATURAL_32 + H5: NATURAL_32 + +feature {NONE} + k1: NATURAL_32 = 0x5a827999 + k2: NATURAL_32 = 0x6ed9eba1 + k3: NATURAL_32 = 0x8f1bbcdc + k4: NATURAL_32 = 0xca62c1d6 + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := current_out + end + +invariant + schedule_lower:schedule.lower = 0 + schedule_upper:schedule.upper = 79 +end diff --git a/library/crypto/eel/digests/SHA256/sha256.e b/library/crypto/eel/digests/SHA256/sha256.e new file mode 100644 index 00000000..e61bbf9f --- /dev/null +++ b/library/crypto/eel/digests/SHA256/sha256.e @@ -0,0 +1,363 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Useless laws weaken the necessary laws. - Montesquieu" + +class + SHA256 + +inherit + ANY + redefine + is_equal + end + DEBUG_OUTPUT + undefine + is_equal + end + SHA_FUNCTIONS + rename + byte_sink as update + export + {SHA256} + schedule, + buffer, + schedule_offset, + byte_count, + buffer_offset + undefine + is_equal + end + ROTATE_FACILITIES + undefine + is_equal + end + +create + make, + make_copy + +feature + make + do + create schedule.make_filled (0, 64) + create buffer.make_filled (0, 4) + reset + end + + make_copy (other: like Current) + do + make + schedule.copy_data (other.schedule, other.schedule.lower, schedule.lower, schedule.count) + buffer.copy_data (other.buffer, other.buffer.lower, buffer.lower, buffer.count) + byte_count := other.byte_count + buffer_offset := other.buffer_offset + h1 := other.h1 + h2 := other.h2 + h3 := other.h3 + h4 := other.h4 + h5 := other.h5 + h6 := other.h6 + h7 := other.h7 + h8 := other.h8 + schedule_offset := other.schedule_offset + ensure + Current ~ other + end + +feature + do_final (output: SPECIAL[NATURAL_8] out_off: INTEGER) + require + valid_offset: out_off >= 0 + out_big_enough: out.count - out_off >= 32 + do + finish + from_natural_32_be (h1, output, out_off) + from_natural_32_be (h2, output, out_off + 4) + from_natural_32_be (h3, output, out_off + 8) + from_natural_32_be (h4, output, out_off + 12) + from_natural_32_be (h5, output, out_off + 16) + from_natural_32_be (h6, output, out_off + 20) + from_natural_32_be (h7, output, out_off + 24) + from_natural_32_be (h8, output, out_off + 28) + reset + end + + reset + do + buffer_offset := 0 + h1 := 0x6a09e667 + h2 := 0xbb67ae85 + h3 := 0x3c6ef372 + h4 := 0xa54ff53a + h5 := 0x510e527f + h6 := 0x9b05688c + h7 := 0x1f83d9ab + h8 := 0x5be0cd19 + schedule_offset := 0 + schedule.fill_with ({NATURAL_32} 0, 0, schedule.upper) + ensure + buffer_reset: buffer_offset = 0 + schedule_reset: schedule_offset = 0 + end + + current_final (output: SPECIAL [NATURAL_8] offset: INTEGER_32) + require + valid_start: output.valid_index (offset) + valid_end: output.valid_index (offset + 31) + local + current_copy: like Current + do + current_copy := Current.deep_twin + current_copy.do_final (output, offset) + end + + current_out: STRING + local + output: SPECIAL [NATURAL_8] + index: INTEGER_32 + do + Result := "0x" + create output.make_filled (0, 32) + current_final (output, 0) + from + index := 0 + until + index = 32 + loop + Result.append (output [index].to_hex_string) + index := index + 1 + end + end + + is_equal (other: like Current): BOOLEAN + do + Result := + schedule.same_items (other.schedule, other.schedule.lower, schedule.lower, schedule.count) and + buffer.same_items (other.buffer, other.buffer.lower, buffer.lower, buffer.count) and + h1 = other.h1 and + h2 = other.h2 and + h3 = other.h3 and + h4 = other.h4 and + h5 = other.h5 and + h6 = other.h6 and + h7 = other.h7 and + h8 = other.h8 and + schedule_offset = other.schedule_offset and + byte_count = other.byte_count and + buffer_offset = other.buffer_offset + end + +feature{NONE} + process_block + local + a: NATURAL_32 + b: NATURAL_32 + c: NATURAL_32 + d: NATURAL_32 + e: NATURAL_32 + f: NATURAL_32 + g: NATURAL_32 + h: NATURAL_32 + t: INTEGER + i: INTEGER + do + expand_blocks + a := h1 + b := h2 + c := h3 + d := h4 + e := h5 + f := h6 + g := h7 + h := h8 + t := 0 + from + i := 0 + until + i = 8 + loop + h := h + sigma1 (e) + ch (e, f, g) + k [t] + schedule [t] + t := t + 1 + d := d + h + h := h + sigma0 (a) + maj (a, b, c) + + g := g + sigma1 (d) + ch (d, e, f) + k [t] + schedule [t] + t := t + 1 + c := c + g + g := g + sigma0 (h) + maj (h, a, b) + + f := f + sigma1 (c) + ch (c, d, e) + k [t] + schedule [t] + t := t + 1 + b := b + f + f := f + sigma0 (g) + maj (g, h, a) + + e := e + sigma1 (b) + ch (b, c, d) + k [t] + schedule [t] + t := t + 1 + a := a + e + e := e + sigma0 (f) + maj (f, g, h) + + d := d + sigma1 (a) + ch (a, b, c) + k [t] + schedule [t] + t := t + 1 + h := h + d + d := d + sigma0 (e) + maj (e, f, g) + + c := c + sigma1 (h) + ch (h, a, b) + k [t] + schedule [t] + t := t + 1 + g := g + c + c := c + sigma0 (d) + maj (d, e, f) + + b := b + sigma1 (g) + ch (g, h, a) + k [t] + schedule [t] + t := t + 1 + f := f + b + b := b + sigma0 (c) + maj (c, d, e) + + a := a + sigma1 (f) + ch (f, g, h) + k [t] + schedule [t] + t := t + 1 + e := e + a + a := a + sigma0 (b) + maj (b, c, d) + + i := i + 1 + end + + h1 := h1 + a + h2 := h2 + b + h3 := h3 + c + h4 := h4 + d + h5 := h5 + e + h6 := h6 + f + h7 := h7 + g + h8 := h8 + h + end + + sigma0 (x1: NATURAL_32): NATURAL_32 + do + result := rotate_right_32 (x1, 2) + result := result.bit_xor (rotate_right_32 (x1, 13)) + result := result.bit_xor (rotate_right_32 (x1, 22)) + end + + sigma1 (x1: NATURAL_32): NATURAL_32 + do + result := rotate_right_32 (x1, 6) + result := result.bit_xor (rotate_right_32 (x1, 11)) + result := result.bit_xor (rotate_right_32 (x1, 25)) + end + + lsigma0(x1: NATURAL_32): NATURAL_32 + do + result := (rotate_right_32 (x1, 7)).bit_xor (rotate_right_32 (x1, 18)).bit_xor (x1 |>> 3) + end + + lsigma1(x1: NATURAL_32): NATURAL_32 + do + result := (rotate_right_32 (x1, 17)).bit_xor (rotate_right_32 (x1, 19)).bit_xor (x1 |>> 10) + end + + expand_blocks + local + t: INTEGER + do + from + t := 16 + until + t = 64 + loop + schedule[t] := lsigma1 (schedule [t - 2]) + schedule [t - 7] + lsigma0 (schedule [t - 15]) + schedule [t - 16] + t := t + 1 + end + end + + k: SPECIAL[NATURAL_32] + once + create result.make_filled (0, 64) + result[0] := 0x428a2f98 + result[1] := 0x71374491 + result[2] := 0xb5c0fbcf + result[3] := 0xe9b5dba5 + result[4] := 0x3956c25b + result[5] := 0x59f111f1 + result[6] := 0x923f82a4 + result[7] := 0xab1c5ed5 + result[8] := 0xd807aa98 + result[9] := 0x12835b01 + result[10] := 0x243185be + result[11] := 0x550c7dc3 + result[12] := 0x72be5d74 + result[13] := 0x80deb1fe + result[14] := 0x9bdc06a7 + result[15] := 0xc19bf174 + result[16] := 0xe49b69c1 + result[17] := 0xefbe4786 + result[18] := 0x0fc19dc6 + result[19] := 0x240ca1cc + result[20] := 0x2de92c6f + result[21] := 0x4a7484aa + result[22] := 0x5cb0a9dc + result[23] := 0x76f988da + result[24] := 0x983e5152 + result[25] := 0xa831c66d + result[26] := 0xb00327c8 + result[27] := 0xbf597fc7 + result[28] := 0xc6e00bf3 + result[29] := 0xd5a79147 + result[30] := 0x06ca6351 + result[31] := 0x14292967 + result[32] := 0x27b70a85 + result[33] := 0x2e1b2138 + result[34] := 0x4d2c6dfc + result[35] := 0x53380d13 + result[36] := 0x650a7354 + result[37] := 0x766a0abb + result[38] := 0x81c2c92e + result[39] := 0x92722c85 + result[40] := 0xa2bfe8a1 + result[41] := 0xa81a664b + result[42] := 0xc24b8b70 + result[43] := 0xc76c51a3 + result[44] := 0xd192e819 + result[45] := 0xd6990624 + result[46] := 0xf40e3585 + result[47] := 0x106aa070 + result[48] := 0x19a4c116 + result[49] := 0x1e376c08 + result[50] := 0x2748774c + result[51] := 0x34b0bcb5 + result[52] := 0x391c0cb3 + result[53] := 0x4ed8aa4a + result[54] := 0x5b9cca4f + result[55] := 0x682e6ff3 + result[56] := 0x748f82ee + result[57] := 0x78a5636f + result[58] := 0x84c87814 + result[59] := 0x8cc70208 + result[60] := 0x90befffa + result[61] := 0xa4506ceb + result[62] := 0xbef9a3f7 + result[63] := 0xc67178f2 + end + +feature {SHA256} + h1: NATURAL_32 + h2: NATURAL_32 + h3: NATURAL_32 + h4: NATURAL_32 + h5: NATURAL_32 + h6: NATURAL_32 + h7: NATURAL_32 + h8: NATURAL_32 + +feature {NONE} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := current_out + end + +invariant + buffer_size: buffer.count = 4 + valid_buffer_offset: buffer.valid_index (buffer_offset) + schedule_size: schedule.count = 64 + valid_schedule_offset: schedule.valid_index (schedule_offset) +end diff --git a/library/crypto/eel/digests/sha_functions.e b/library/crypto/eel/digests/sha_functions.e new file mode 100644 index 00000000..d2a56e72 --- /dev/null +++ b/library/crypto/eel/digests/sha_functions.e @@ -0,0 +1,118 @@ +note + description: "Summary description for {SHA_FUNCTIONS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The war for freedom will never really be won because the price of our freedom is constant vigilance over ourselves and over our Government. - Eleanor Roosevelt" + +deferred class + SHA_FUNCTIONS + +inherit + BYTE_FACILITIES + BYTE_32_BIT_BLOCK_FACILITIES + redefine + update + end + +feature {NONE} + ch (u: NATURAL_32 v: NATURAL_32 w: NATURAL_32): NATURAL_32 + do + result := (u & v) | (u.bit_not & w) + end + + maj (u: NATURAL_32 v: NATURAL_32 w: NATURAL_32): NATURAL_32 + do + result := (u & v) | (u & w) | (v & w) + end + + parity (u: NATURAL_32 v: NATURAL_32 w: NATURAL_32): NATURAL_32 + do + result := u.bit_xor (v).bit_xor (w) + end + +feature {NONE} -- Padding facilities + pad + local + pad_bytes: INTEGER_32 + do + update (0b1000_0000) + from + pad_bytes := (56 - (byte_count \\ 64)).to_integer_32 + if + pad_bytes < 0 + then + pad_bytes := pad_bytes + 64 + end + until + pad_bytes = 0 + loop + update (0) + pad_bytes := pad_bytes - 1 + end + end + + byte_count: NATURAL_64 + + bit_count: NATURAL_64 + do + result := byte_count |<< 3 + end + + update (in: NATURAL_8) + do + precursor (in) + byte_count := byte_count + 1 + ensure then + byte_count = old byte_count + 1 + end + +feature {NONE} -- Length processing facilities + process_length (length: NATURAL_64) + require + schedule_start: schedule_offset = 14 + empty_buffer: buffer_offset = 0 + do + update_word ((length |>> 32).to_natural_32) + update_word (length.to_natural_32) + ensure + empty_buffer: buffer_offset = 0 + schedule_end: schedule_offset = 0 + end + + process_word (in: SPECIAL [NATURAL_8] offset: INTEGER_32) + do + schedule [schedule_offset] := as_natural_32_be (in, offset) + schedule_offset := schedule_offset + 1 + if + schedule_offset = 16 + then + schedule_offset := 0 + process_block + end + end + + process_block + deferred + end + + finish + local + length: NATURAL_64 + do + length := bit_count + pad + process_length (length) + end + +feature {NONE} + schedule: SPECIAL [NATURAL_32] + schedule_offset: INTEGER_32 + +invariant + valid_schedule_offset: schedule.valid_index (schedule_offset) + valid_schedule_offset_lower: schedule_offset >= 0 + valid_schedule_offset_upper: schedule_offset <= 15 + valid_schedule_lower: schedule.valid_index (0) + valid_schedule_upper: schedule.valid_index (15) +end diff --git a/library/crypto/eel/digests/sha_functions.e.orig b/library/crypto/eel/digests/sha_functions.e.orig new file mode 100644 index 00000000..46ac0a54 --- /dev/null +++ b/library/crypto/eel/digests/sha_functions.e.orig @@ -0,0 +1,118 @@ +note + description: "Summary description for {SHA_FUNCTIONS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The war for freedom will never really be won because the price of our freedom is constant vigilance over ourselves and over our Government. - Eleanor Roosevelt" + +deferred class + SHA_FUNCTIONS + +inherit + BYTE_FACILITIES + BYTE_32_BIT_BLOCK_FACILITIES + redefine + update + end + +feature {NONE} + ch (u: NATURAL_32; v: NATURAL_32; w: NATURAL_32): NATURAL_32 is + do + result := (u & v) | (u.bit_not & w) + end + + maj (u: NATURAL_32; v: NATURAL_32; w: NATURAL_32): NATURAL_32 is + do + result := (u & v) | (u & w) | (v & w) + end + + parity (u: NATURAL_32; v: NATURAL_32; w: NATURAL_32): NATURAL_32 is + do + result := u.bit_xor (v).bit_xor (w) + end + +feature {NONE} -- Padding facilities + pad + local + pad_bytes: INTEGER_32 + do + update (0b1000_0000) + from + pad_bytes := (56 - (byte_count \\ 64)).to_integer_32 + if + pad_bytes < 0 + then + pad_bytes := pad_bytes + 64 + end + until + pad_bytes = 0 + loop + update (0) + pad_bytes := pad_bytes - 1 + end + end + + byte_count: NATURAL_64 + + bit_count: NATURAL_64 + do + result := byte_count |<< 3 + end + + update (in: NATURAL_8) + do + precursor (in) + byte_count := byte_count + 1 + ensure then + byte_count = old byte_count + 1 + end + +feature {NONE} -- Length processing facilities + process_length (length: NATURAL_64) + require + schedule_start: schedule_offset = 14 + empty_buffer: buffer_offset = 0 + do + update_word ((length |>> 32).to_natural_32) + update_word (length.to_natural_32) + ensure + empty_buffer: buffer_offset = 0 + schedule_end: schedule_offset = 0 + end + + process_word (in: SPECIAL [NATURAL_8]; offset: INTEGER_32) + do + schedule [schedule_offset] := as_natural_32_be (in, offset) + schedule_offset := schedule_offset + 1 + if + schedule_offset = 16 + then + schedule_offset := 0 + process_block + end + end + + process_block + deferred + end + + finish is + local + length: NATURAL_64 + do + length := bit_count + pad + process_length (length) + end + +feature {NONE} + schedule: SPECIAL [NATURAL_32] + schedule_offset: INTEGER_32 + +invariant + valid_schedule_offset: schedule.valid_index (schedule_offset) + valid_schedule_offset_lower: schedule_offset >= 0 + valid_schedule_offset_upper: schedule_offset <= 15 + valid_schedule_lower: schedule.valid_index (0) + valid_schedule_upper: schedule.valid_index (15) +end diff --git a/library/crypto/eel/ec/ec_constants.e b/library/crypto/eel/ec/ec_constants.e new file mode 100644 index 00000000..f5db6c73 --- /dev/null +++ b/library/crypto/eel/ec/ec_constants.e @@ -0,0 +1,14 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The natural progress of things is for liberty to yield and government to gain ground. - Thomas Jefferson" + +deferred class + EC_CONSTANTS + +inherit + CONSTANTS + +end diff --git a/library/crypto/eel/ec/ec_curve.e b/library/crypto/eel/ec/ec_curve.e new file mode 100644 index 00000000..d7f2ae4e --- /dev/null +++ b/library/crypto/eel/ec/ec_curve.e @@ -0,0 +1,23 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "None are more hopelessly enslaved than those who falsely believe they are free. - Goethe" + +deferred class + EC_CURVE + +inherit + DEBUG_OUTPUT + +feature + a: EC_FIELD_ELEMENT + b: EC_FIELD_ELEMENT + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := "a: " + a.debug_output + "%Nb: " + b.debug_output + end +end diff --git a/library/crypto/eel/ec/ec_curve_f2m.e b/library/crypto/eel/ec/ec_curve_f2m.e new file mode 100644 index 00000000..74f31a5c --- /dev/null +++ b/library/crypto/eel/ec/ec_curve_f2m.e @@ -0,0 +1,419 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "When the government's boot is on your throat, whether it is a left boot or a right boot is of no consequence. - Gary Lloyd" + +class + EC_CURVE_F2M + +inherit + EC_CURVE + redefine + is_equal, + a, + b + end + STANDARD_CURVES + undefine + is_equal + end + F2M_REPRESENTATIONS + undefine + is_equal + end + +create + make, + make_sec_t113r1, + make_sec_t113r2, + make_sec_t131r1, + make_sec_t131r2, + make_sec_t163k1, + make_sec_t163r1, + make_sec_t163r2, + make_sec_t193r1, + make_sec_t193r2, + make_sec_t233k1, + make_sec_t233r1, + make_sec_t239k1, + make_sec_t283k1, + make_sec_t283r1, + make_sec_t409k1, + make_sec_t409r1, + make_sec_t571k1, + make_sec_t571r1, + make_k163, + make_k233, + make_k283, + make_k409, + make_k571, + make_b163, + make_b233, + make_b283, + make_b409, + make_b571 + +feature -- SEC curves + make_sec_t113r1 + do + m := sec_t113r1_m + k1 := sec_t113r1_k1 + k2 := sec_t113r1_k2 + k3 := sec_t113r1_k3 + n := sec_t113r1_r + create a.make (sec_t113r1_a) + create b.make (sec_t113r1_b) + end + + make_sec_t113r2 + do + m := sec_t113r2_m + k1 := sec_t113r2_k1 + k2 := sec_t113r2_k2 + k3 := sec_t113r2_k3 + n := sec_t113r2_r + create a.make (sec_t113r2_a) + create b.make (sec_t113r2_b) + end + + make_sec_t131r1 + do + m := sec_t131r1_m + k1 := sec_t131r1_k1 + k2 := sec_t131r1_k2 + k3 := sec_t131r1_k3 + n := sec_t131r1_r + create a.make (sec_t131r1_a) + create b.make (sec_t131r1_b) + end + + make_sec_t131r2 + do + m := sec_t131r2_m + k1 := sec_t131r2_k1 + k2 := sec_t131r2_k2 + k3 := sec_t131r2_k3 + n := sec_t131r2_r + create a.make (sec_t131r2_a) + create b.make (sec_t131r2_b) + end + + make_sec_t163k1 + do + m := sec_t163k1_m + k1 := sec_t163k1_k1 + k2 := sec_t163k1_k2 + k3 := sec_t163k1_k3 + n := sec_t163k1_r + create a.make (sec_t163k1_a) + create b.make (sec_t163k1_b) + end + + make_sec_t163r1 + do + m := sec_t163r1_m + k1 := sec_t163r1_k1 + k2 := sec_t163r1_k2 + k3 := sec_t163r1_k3 + n := sec_t163r1_r + create a.make (sec_t163r1_a) + create b.make (sec_t163r1_b) + end + + make_sec_t163r2 + do + m := sec_t163r2_m + k1 := sec_t163r2_k1 + k2 := sec_t163r2_k2 + k3 := sec_t163r2_k3 + n := sec_t163r1_r + create a.make (sec_t163r2_a) + create b.make (sec_t163r2_b) + end + + make_sec_t193r1 + do + m := sec_t193r1_m + k1 := sec_t193r1_k1 + k2 := sec_t193r1_k2 + k3 := sec_t193r1_k3 + n := sec_t193r1_r + create a.make (sec_t193r1_a) + create b.make (sec_t193r1_b) + end + + make_sec_t193r2 + do + m := sec_t193r2_m + k1 := sec_t193r2_k1 + k2 := sec_t193r2_k2 + k3 := sec_t193r2_k3 + n := sec_t193r2_r + create a.make (sec_t193r2_a) + create b.make (sec_t193r2_b) + end + + make_sec_t233k1 + do + m := sec_t233k1_m + k1 := sec_t233k1_k1 + k2 := sec_t233k1_k2 + k3 := sec_t233k1_k3 + n := sec_t233k1_r + create a.make (sec_t233k1_a) + create b.make (sec_t233k1_b) + end + + make_sec_t233r1 + do + m := sec_t233r1_m + k1 := sec_t233r1_k1 + k2 := sec_t233r1_k2 + k3 := sec_t233r1_k3 + n := sec_t233r1_r + create a.make (sec_t233r1_a) + create b.make (sec_t233r1_b) + end + + make_sec_t239k1 + do + m := sec_t239k1_m + k1 := sec_t239k1_k1 + k2 := sec_t239k1_k2 + k3 := sec_t239k1_k3 + n := sec_t239k1_r + create a.make (sec_t239k1_a) + create b.make (sec_t239k1_b) + end + + make_sec_t283k1 + do + m := sec_t283k1_m + k1 := sec_t283k1_k1 + k2 := sec_t283k1_k2 + k3 := sec_t283k1_k3 + n := sec_t283k1_r + create a.make (sec_t283k1_a) + create b.make (sec_t283k1_b) + end + + make_sec_t283r1 + do + m := sec_t283r1_m + k1 := sec_t283r1_k1 + k2 := sec_t283r1_k2 + k3 := sec_t283r1_k3 + n := sec_t283r1_r + create a.make (sec_t283r1_a) + create b.make (sec_t283r1_b) + end + + make_sec_t409k1 + do + m := sec_t409k1_m + k1 := sec_t409k1_k1 + k2 := sec_t409k1_k2 + k3 := sec_t409k1_k3 + n := sec_t409k1_r + create a.make (sec_t409k1_a) + create b.make (sec_t409k1_b) + end + + make_sec_t409r1 + do + m := sec_t409r1_m + k1 := sec_t409r1_k1 + k2 := sec_t409r1_k2 + k3 := sec_t409r1_k3 + n := sec_t409r1_r + create a.make (sec_t409r1_a) + create b.make (sec_t409r1_b) + end + + make_sec_t571k1 + do + m := sec_t571k1_m + k1 := sec_t571k1_k1 + k2 := sec_t571k1_k2 + k3 := sec_t571k1_k3 + n := sec_t571k1_r + create a.make (sec_t571k1_a) + create b.make (sec_t571k1_b) + end + + make_sec_t571r1 + do + m := sec_t571r1_m + k1 := sec_t571r1_k1 + k2 := sec_t571r1_k2 + k3 := sec_t571r1_k3 + n := sec_t571r1_r + create a.make (sec_t571r1_a) + create b.make (sec_t571r1_b) + end + +feature -- FIPS curves + make_k163 + do + m := k163_m + k1 := k163_k1 + k2 := k163_k2 + k3 := k163_k3 + n := k163_r + create a.make (k163_a) + create b.make (k163_b) + end + + make_k233 + do + m := k233_m + k1 := k233_k1 + k2 := k233_k2 + k3 := k233_k3 + n := k233_r + create a.make (k233_a) + create b.make (k233_b) + end + + make_k283 + do + m := k283_m + k1 := k283_k1 + k2 := k283_k2 + k3 := k283_k3 + n := k283_r + create a.make (k283_a) + create b.make (k283_b) + end + + make_k409 + do + m := k409_m + k1 := k409_k1 + k2 := k409_k2 + k3 := k409_k3 + n := k409_r + create a.make (k409_a) + create b.make (k409_b) + end + + make_k571 + do + m := k571_m + k1 := k571_k1 + k2 := k571_k2 + k3 := k571_k3 + n := k571_r + create a.make (k571_a) + create b.make (k571_b) + end + + make_b163 + do + m := b163_m + k1 := b163_k1 + k2 := b163_k2 + k3 := b163_k3 + n := b163_r + create a.make (b163_a) + create b.make (b163_b) + end + + make_b233 + do + m := b233_m + k1 := b233_k1 + k2 := b233_k2 + k3 := b233_k3 + n := b233_r + create a.make (b233_a) + create b.make (b233_b) + end + + make_b283 + do + m := b283_m + k1 := b283_k1 + k2 := b283_k2 + k3 := b283_k3 + n := b283_r + create a.make (b283_a) + create b.make (b283_b) + end + + make_b409 + do + m := b409_m + k1 := b409_k1 + k2 := b409_k2 + k3 := b409_k3 + n := b409_r + create a.make (b409_a) + create b.make (b409_b) + end + + make_b571 + do + m := b571_m + k1 := b571_k1 + k2 := b571_k2 + k3 := b571_k3 + n := b571_r + create a.make (b571_a) + create b.make (b571_b) + end + + make (m_new: INTEGER_32 k1_new: INTEGER_32 k2_new: INTEGER_32 k3_new: INTEGER_32 a_a: EC_FIELD_ELEMENT_F2M b_a: EC_FIELD_ELEMENT_F2M n_a: INTEGER_X) + require + K1_greater_Than_zero: k1_new > 0 + k2_and_k3_equal_zero: (k2_new = 0) implies (k3_new = 0) + k2_greater_than_k1: (k2_new /= 0) implies (k2_new > k1_new) + k3_greater_than_k2: (k3_new /= 0) implies (k3_new > k2_new) + do + m := m_new + k1 := k1_new + k2 := k2_new + k3 := k3_new + a := a_a + b := b_a + n := n_a + end + +feature -- F2M components + m: INTEGER_32 + n: INTEGER_X + k1: INTEGER_32 + k2: INTEGER_32 + k3: INTEGER_32 + +feature + representation: INTEGER + do + if + k2 = 0 + then + result := TPB + else + result := PPB + end + + end + + is_equal (other: like current): BOOLEAN + do + Result := (m = other.m) and (k1 = other.k1) and (k2 = other.k2) and (k3 = other.k3) and a.x ~ other.a.x and b.x ~ other.b.x + end + + a: EC_FIELD_ELEMENT_F2M + b: EC_FIELD_ELEMENT_F2M + +invariant +-- k2_smaller: k2 = 0 implies k2 < k3 +-- k2_zero: k2 = 0 implies k2 /= 0 + K1_greater_Than_zero: k1 > 0 + k2_and_k3_equal_zero: (k2 = 0) implies (k3 = 0) + k2_greater_than_k1: (k2 /= 0) implies (k2 > k1) + k3_greater_than_k2: (k3 /= 0) implies (k3 > k2) +end diff --git a/library/crypto/eel/ec/ec_curve_fp.e b/library/crypto/eel/ec/ec_curve_fp.e new file mode 100644 index 00000000..20275334 --- /dev/null +++ b/library/crypto/eel/ec/ec_curve_fp.e @@ -0,0 +1,230 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Every decent man is ashamed of the government he lives under. - H.L. Mencken" + +class + EC_CURVE_FP + +inherit + EC_CONSTANTS + undefine + is_equal + end + EC_CURVE + redefine + is_equal, + a, + b + end + STANDARD_CURVES + undefine + is_equal + end + +create + make_q_a_b, + make_sec_p112r1, + make_sec_p112r2, + make_sec_p128r1, + make_sec_p128r2, + make_sec_p160k1, + make_sec_p160r1, + make_sec_p160r2, + make_sec_p192k1, + make_sec_p192r1, + make_sec_p224k1, + make_sec_p224r1, + make_sec_p256k1, + make_sec_p256r1, + make_sec_p384r1, + make_sec_p521r1, + make_p192, + make_p224, + make_p256, + make_p384, + make_p521 + +create {EC_FIELD_ELEMENT_FP} + make_zero + +feature {EC_FIELD_ELEMENT_FP} + make_zero + do + create q.default_create + create a.make_zero + create b.make_zero + end + +feature + make_q_a_b (q_new: INTEGER_X a_a: INTEGER_X b_a: INTEGER_X) + -- Create an EC over FP from q, a, and b + do + q := q_new + create a.make_p_x (a_a) + create b.make_p_x (b_a) + end + +feature -- SEC curves + make_sec_p112r1 + do + q := sec_p112r1_p + create a.make_p_x (sec_p112r1_a) + create b.make_p_x (sec_p112r1_b) + end + + make_sec_p112r2 + do + q := sec_p112r2_p + create a.make_p_x (sec_p112r2_a) + create b.make_p_x (sec_p112r2_b) + end + + make_sec_p128r1 + do + q := sec_p128r1_p + create a.make_p_x (sec_p128r1_a) + create b.make_p_x (sec_p128r1_b) + end + + make_sec_p128r2 + do + q := sec_p128r2_p + create a.make_p_x (sec_p128r2_a) + create b.make_p_x (sec_p128r2_b) + end + + make_sec_p160k1 + do + q := sec_p160k1_p + create a.make_p_x (sec_p160k1_a) + create b.make_p_x (sec_p160k1_b) + end + + make_sec_p160r1 + do + q := sec_p160r1_p + create a.make_p_x (sec_p160r1_a) + create b.make_p_x (sec_p160r1_b) + end + + make_sec_p160r2 + do + q := sec_p160r2_p + create a.make_p_x (sec_p160r2_a) + create b.make_p_x (sec_p160r2_b) + end + + make_sec_p192k1 + do + q := sec_p192k1_p + create a.make_p_x (sec_p192k1_a) + create b.make_p_x (sec_p192k1_b) + end + + make_sec_p192r1 + do + q := sec_p192r1_p + create a.make_p_x (sec_p192r1_a) + create b.make_p_x (sec_p192r1_b) + end + + make_sec_p224k1 + do + q := sec_p224k1_p + create a.make_p_x (sec_p224k1_a) + create b.make_p_x (sec_p224k1_b) + end + + make_sec_p224r1 + do + q := sec_p224r1_p + create a.make_p_x (sec_p224r1_a) + create b.make_p_x (sec_p224r1_b) + end + + make_sec_p256k1 + do + q := sec_p256k1_p + create a.make_p_x (sec_p256k1_a) + create b.make_p_x (sec_p256k1_b) + end + + make_sec_p256r1 + do + q := sec_p256r1_p + create a.make_p_x (sec_p256r1_a) + create b.make_p_x (sec_p256r1_b) + end + + make_sec_p384r1 + do + q := sec_p384r1_p + create a.make_p_x (sec_p384r1_a) + create b.make_p_x (sec_p384r1_b) + end + + make_sec_p521r1 + do + q := sec_p521r1_p + create a.make_p_x (sec_p521r1_a) + create b.make_p_x (sec_p521r1_b) + end + +feature + make_p192 + do + q := p192_p + create a.make_p_x (p192_a) + create b.make_p_x (p192_b) + end + + make_p224 + do + q := p224_p + create a.make_p_x (p224_a) + create b.make_p_x (p224_b) + end + + make_p256 + do + q := p256_p + create a.make_p_x (p256_a) + create b.make_p_x (p256_b) + end + + make_p384 + do + q := p384_p + create a.make_p_x (p384_a) + create b.make_p_x (p384_b) + end + + make_p521 + do + q := p521_p + create a.make_p_x (p521_a) + create b.make_p_x (p521_b) + end + +feature + q: INTEGER_X + a: EC_FIELD_ELEMENT_FP + attribute + create result.make_zero + end + b: EC_FIELD_ELEMENT_FP + attribute + create result.make_zero + end + + is_equal (other: like current): BOOLEAN + -- Is current equal to other + do + result := q ~ other.q and a.x ~ other.a.x and b.x ~ other.b.x + ensure then + q /~ other.q implies not result + end +end diff --git a/library/crypto/eel/ec/ec_domain_parameters.e b/library/crypto/eel/ec/ec_domain_parameters.e new file mode 100644 index 00000000..ea5771a7 --- /dev/null +++ b/library/crypto/eel/ec/ec_domain_parameters.e @@ -0,0 +1,44 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The urge to save humanity is almost always a false front for the urge to rule. - H.L. Mencken" + +deferred class + EC_DOMAIN_PARAMETERS + +inherit + EC_CONSTANTS + DEBUG_OUTPUT + +feature + curve: EC_CURVE + g: EC_POINT + n: INTEGER_X + h: INTEGER_X + + make_curve_g_n (curve_new: like curve g_new: like g n_new: INTEGER_X) + -- Construct this domain with no seed and h= 1 + do + curve := curve_new + g := g_new + n := n_new + h := ONE + end + + make_curve_g_n_h (curve_new: like curve g_new: like g n_new: INTEGER_X h_new: INTEGER_X) + -- construct this domain with no seed + do + curve := curve_new + g := g_new + n := n_new + h := h_new + end + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := "Curve: " + curve.debug_output + "%Ng: " + g.debug_output + "%Nn: " + n.out_hex + "%Nh: " + h.out_hex + end +end diff --git a/library/crypto/eel/ec/ec_domain_parameters.e.orig b/library/crypto/eel/ec/ec_domain_parameters.e.orig new file mode 100644 index 00000000..3754f986 --- /dev/null +++ b/library/crypto/eel/ec/ec_domain_parameters.e.orig @@ -0,0 +1,44 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The urge to save humanity is almost always a false front for the urge to rule. - H.L. Mencken" + +deferred class + EC_DOMAIN_PARAMETERS + +inherit + EC_CONSTANTS + DEBUG_OUTPUT + +feature + curve: EC_CURVE + g: EC_POINT + n: INTEGER_X + h: INTEGER_X + + make_curve_g_n (curve_new: like curve; g_new: like g; n_new: INTEGER_X) is + -- Construct this domain with no seed and h= 1 + do + curve := curve_new + g := g_new + n := n_new + h := ONE + end + + make_curve_g_n_h (curve_new: like curve g_new: like g n_new: INTEGER_X h_new: INTEGER_X) is + -- construct this domain with no seed + do + curve := curve_new + g := g_new + n := n_new + h := h_new + end + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := "Curve: " + curve.debug_output + "%Ng: " + g.debug_output + "%Nn: " + n.out_hex + "%Nh: " + h.out_hex + end +end diff --git a/library/crypto/eel/ec/ec_domain_parameters_f2m.e b/library/crypto/eel/ec/ec_domain_parameters_f2m.e new file mode 100644 index 00000000..fa5a5347 --- /dev/null +++ b/library/crypto/eel/ec/ec_domain_parameters_f2m.e @@ -0,0 +1,279 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Where morality is present, laws are unnecessary. Without morality, laws are unenforceable. - Anonymous" + +class + EC_DOMAIN_PARAMETERS_F2M + +inherit + EC_DOMAIN_PARAMETERS + redefine + curve, + g + end + STANDARD_CURVES + +create + make_curve_g_n, + make_curve_g_n_h, + make_sec_t113r1, + make_sec_t113r2, + make_sec_t131r1, + make_sec_t131r2, + make_sec_t163k1, + make_sec_t163r1, + make_sec_t163r2, + make_sec_t193r1, + make_sec_t193r2, + make_sec_t233k1, + make_sec_t233r1, + make_sec_t239k1, + make_sec_t283k1, + make_sec_t283r1, + make_sec_t409k1, + make_sec_t409r1, + make_sec_t571k1, + make_sec_t571r1, + make_k163, + make_k233, + make_k283, + make_k409, + make_k571, + make_b163, + make_b233, + make_b283, + make_b409, + make_b571 + +feature --SEC recommended polynomial curves + make_sec_t113r1 + do + create curve.make_sec_t113r1 + create g.make_sec_t113r1 + n := sec_t113r1_r + h := sec_t113r1_h + end + + make_sec_t113r2 + do + create curve.make_sec_t113r2 + create g.make_sec_t113r2 + n := sec_t113r2_r + h := sec_t113r2_h + end + + make_sec_t131r1 + do + create curve.make_sec_t131r1 + create g.make_sec_t131r1 + n := sec_t131r1_r + h := sec_t131r1_h + end + + make_sec_t131r2 + do + create curve.make_sec_t131r2 + create g.make_sec_t131r2 + n := sec_t131r2_r + h := sec_t131r2_h + end + + make_sec_t163k1 + do + create curve.make_sec_t163k1 + create g.make_sec_t163k1 + n := sec_t163k1_r + h := sec_t163k1_h + end + + make_sec_t163r1 + do + create curve.make_sec_t163r1 + create g.make_sec_t163r1 + n := sec_t163r1_r + h := sec_t163r1_h + end + + make_sec_t163r2 + do + create curve.make_sec_t163r2 + create g.make_sec_t163r2 + n := sec_t163r2_r + h := sec_t163r2_h + end + + make_sec_t193r1 + do + create curve.make_sec_t193r1 + create g.make_sec_t193r1 + n := sec_t193r1_r + h := sec_t193r1_h + end + + make_sec_t193r2 + do + create curve.make_sec_t193r2 + create g.make_sec_t193r2 + n := sec_t193r2_r + h := sec_t193r2_h + end + + make_sec_t233k1 + do + create curve.make_sec_t233k1 + create g.make_sec_t233k1 + n := sec_t233k1_r + h := sec_t233k1_h + end + + make_sec_t233r1 + do + create curve.make_sec_t233r1 + create g.make_sec_t233r1 + n := sec_t233r1_r + h := sec_t233r1_h + end + + make_sec_t239k1 + do + create curve.make_sec_t239k1 + create g.make_sec_t239k1 + n := sec_t239k1_r + h := sec_t239k1_h + end + + make_sec_t283k1 + do + create curve.make_sec_t283k1 + create g.make_sec_t283k1 + n := sec_t283k1_r + h := sec_t283k1_h + end + + make_sec_t283r1 + do + create curve.make_sec_t283r1 + create g.make_sec_t283r1 + n := sec_t283r1_r + h := sec_t283r1_h + end + + make_sec_t409k1 + do + create curve.make_sec_t409k1 + create g.make_sec_t409k1 + n := sec_t409k1_r + h := sec_t409k1_h + end + + make_sec_t409r1 + do + create curve.make_sec_t409r1 + create g.make_sec_t409r1 + n := sec_t409r1_r + h := sec_t409r1_h + end + + make_sec_t571k1 + do + create curve.make_sec_t571k1 + create g.make_sec_t571k1 + n := sec_t571k1_r + h := sec_t571k1_h + end + + make_sec_t571r1 + do + create curve.make_sec_t571r1 + create g.make_sec_t571r1 + n := sec_t571r1_r + h := sec_t571r1_h + end + +feature --FIPS curves + make_k163 + do + create curve.make_k163 + create g.make_k163 + n := k163_r + h := k163_h + end + + make_k233 + do + create curve.make_k233 + create g.make_k233 + n := k233_r + h := k233_h + end + + make_k283 + do + create curve.make_k283 + create g.make_k283 + n := k283_r + h := k283_h + end + + make_k409 + do + create curve.make_k409 + create g.make_k409 + n := k409_r + h := k409_h + end + + make_k571 + do + create curve.make_k571 + create g.make_k571 + n := k571_r + h := k571_h + end + + make_b163 + do + create curve.make_b163 + create g.make_b163 + n := b163_r + h := b163_h + end + + make_b233 + do + create curve.make_b233 + create g.make_b233 + n := b233_r + h := b233_h + end + + make_b283 + do + create curve.make_b283 + create g.make_b283 + n := b283_r + h := b283_h + end + + make_b409 + do + create curve.make_b409 + create g.make_b409 + n := b409_r + h := b409_h + end + + make_b571 + do + create curve.make_b571 + create g.make_b571 + n := b571_r + h := b571_h + end + + curve: EC_CURVE_F2M + g: EC_POINT_F2M +end diff --git a/library/crypto/eel/ec/ec_domain_parameters_fp.e b/library/crypto/eel/ec/ec_domain_parameters_fp.e new file mode 100644 index 00000000..2f4d4fe2 --- /dev/null +++ b/library/crypto/eel/ec/ec_domain_parameters_fp.e @@ -0,0 +1,214 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Extremism in the defense of liberty is no vice. Moderation in the pursuit of justice is no virtue. - Barry Goldwater (1964)" + +class + EC_DOMAIN_PARAMETERS_FP + +inherit + EC_DOMAIN_PARAMETERS + redefine + curve, + g + end + STANDARD_CURVES + export + {NONE} + all + undefine + default_create + end + +create + make_curve_g_n, + make_curve_g_n_h, + make_sec_p112r1, + make_sec_p112r2, + make_sec_p128r1, + make_sec_p128r2, + make_sec_p160k1, + make_sec_p160r1, + make_sec_p160r2, + make_sec_p192k1, + make_sec_p192r1, + make_sec_p224k1, + make_sec_p224r1, + make_sec_p256k1, + make_sec_p256r1, + make_sec_p384r1, + make_sec_p521r1, + make_p192, + make_p224, + make_p256, + make_p384, + make_p521 + +feature + make_sec_p112r1 + do + create curve.make_sec_p112r1 + create g.make_sec_p112r1 + n := sec_p112r1_r + h := sec_p112r1_h + end + + make_sec_p112r2 + do + create curve.make_sec_p112r2 + create g.make_sec_p112r2 + n := sec_p112r2_r + h := sec_p112r2_h + end + + make_sec_p128r1 + do + create curve.make_sec_p128r1 + create g.make_sec_p128r1 + n := sec_p128r1_r + h := sec_p128r1_h + end + + make_sec_p128r2 + do + create curve.make_sec_p128r2 + create g.make_sec_p128r2 + n := sec_p128r2_r + h := sec_p128r2_h + end + + make_sec_p160k1 + do + create curve.make_sec_p160k1 + create g.make_sec_p160k1 + n := sec_p160k1_r + h := sec_p160k1_h + end + + make_sec_p160r1 + do + create curve.make_sec_p160r1 + create g.make_sec_p160r1 + n := sec_p160r1_r + h := sec_p160r1_h + end + + make_sec_p160r2 + do + create curve.make_sec_p160r2 + create g.make_sec_p160r2 + n := sec_p160r2_r + h := sec_p160r2_h + end + + make_sec_p192k1 + do + create curve.make_sec_p192k1 + create g.make_sec_p192k1 + n := sec_p192k1_r + h := sec_p192k1_h + end + + make_sec_p192r1 + do + create curve.make_sec_p192r1 + create g.make_sec_p192r1 + n := sec_p192r1_r + h := sec_p192r1_h + end + + make_sec_p224k1 + do + create curve.make_sec_p224k1 + create g.make_sec_p224k1 + n := sec_p224k1_r + h := sec_p224k1_h + end + + make_sec_p224r1 + do + create curve.make_sec_p224r1 + create g.make_sec_p224r1 + n := sec_p224r1_r + h := sec_p224r1_h + end + + make_sec_p256k1 + do + create curve.make_sec_p256k1 + create g.make_sec_p256k1 + n := sec_p256k1_r + h := sec_p256k1_h + end + + make_sec_p256r1 + do + create curve.make_sec_p256r1 + create g.make_sec_p256r1 + n := sec_p256r1_r + h := sec_p256r1_h + end + + make_sec_p384r1 + do + create curve.make_sec_p384r1 + create g.make_sec_p384r1 + n := sec_p384r1_r + h := sec_p384r1_h + end + + make_sec_p521r1 + do + create curve.make_sec_p521r1 + create g.make_sec_p521r1 + n := sec_p521r1_r + h := sec_p521r1_h + end + + make_p192 + do + create curve.make_p192 + create g.make_p192 + n := p192_r + h := p192_h + end + + make_p224 + do + create curve.make_p224 + create g.make_p224 + n := p224_r + h := p224_h + end + + make_p256 + do + create curve.make_p256 + create g.make_p256 + n := p256_r + h := p256_h + end + + make_p384 + do + create curve.make_p384 + create g.make_p384 + n := p384_r + h := p384_h + end + + make_p521 + do + create curve.make_p521 + create g.make_p521 + n := p521_r + h := p521_h + end + +feature + curve: EC_CURVE_FP + g: EC_POINT_FP + +end diff --git a/library/crypto/eel/ec/ec_field_element.e b/library/crypto/eel/ec/ec_field_element.e new file mode 100644 index 00000000..c8fd3eb5 --- /dev/null +++ b/library/crypto/eel/ec/ec_field_element.e @@ -0,0 +1,134 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Liberty is not a means to a political end. It is itself the highest political end. - Lord Acton" + +deferred class + EC_FIELD_ELEMENT + +inherit + ANY + redefine + is_equal, + copy + end + DEBUG_OUTPUT + undefine + is_equal, + copy + end + EC_CONSTANTS + undefine + is_equal, + copy + end + +feature + + x: INTEGER_X + + copy (other: like Current) + do + x.copy (other.x) + end + + encoded_field_size (curve: EC_CURVE): INTEGER_32 + -- Return the size of this ecfieldelement in bytes when encoded according to x9.62 + -- This was added as a deviation from the lcrypto origional and seems to be cleaner + -- Replacement for class X9IntegerConverter + deferred + end + + plus (other: like Current; curve: EC_CURVE) + deferred + end + + plus_value (other: like Current; curve: EC_CURVE): like Current + do + Result := deep_twin + Result.plus (other, curve) + end + + minus (other: like Current; curve: EC_CURVE) + deferred + end + + minus_value (other: like Current; curve: EC_CURVE): like Current + do + Result := deep_twin + Result.minus (other, curve) + end + + product (other: like Current; curve: EC_CURVE) + deferred + end + + product_value (other: like Current; curve: EC_CURVE): like Current + do + Result := deep_twin + Result.product (other, curve) + end + + quotient (other: like Current; curve: EC_CURVE) + deferred + end + + quotient_value (other: like Current; curve: EC_CURVE): like Current + do + Result := deep_twin + Result.quotient (other, curve) + end + + opposite (curve: EC_CURVE) + deferred + end + + opposite_value (curve: EC_CURVE): like Current + do + Result := deep_twin + Result.opposite (curve) + end + + square (curve: EC_CURVE) + deferred + end + + square_value (curve: EC_CURVE): like Current + do + Result := deep_twin + Result.square (curve) + end + + inverse (curve: EC_CURVE) + deferred + end + + inverse_value (curve: EC_CURVE): like Current + do + Result := deep_twin + Result.inverse (curve) + end + + sqrt (curve: EC_CURVE): like Current + -- Return a new ECFIELDELEMENT that is sqrt(current) + deferred + end + + is_equal (other: like Current): BOOLEAN + do + Result := x ~ other.x + ensure then + Result = (x ~ other.x) + end + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := x.out_hex + end + +invariant + negative: not x.is_negative +end diff --git a/library/crypto/eel/ec/ec_field_element_f2m.e b/library/crypto/eel/ec/ec_field_element_f2m.e new file mode 100644 index 00000000..29f80cb0 --- /dev/null +++ b/library/crypto/eel/ec/ec_field_element_f2m.e @@ -0,0 +1,518 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The power to tax is the power to destroy. - John Marshall" + +class + EC_FIELD_ELEMENT_F2M + +inherit + EC_FIELD_ELEMENT + redefine + is_equal, + plus_value, + minus_value, + product_value, + quotient_value, + opposite_value, + square_value, + inverse_value + end + + F2M_REPRESENTATIONS + undefine + is_equal, + copy + end + + INTEGER_X_FACILITIES + undefine + is_equal, + copy + end + + LIMB_MANIPULATION + undefine + is_equal, + copy + end + + SPECIAL_UTILITY + undefine + is_equal, + copy + end + +create + make + +convert + make ({INTEGER_X}) + +feature {NONE} + + make (x_a: INTEGER_X) + require + non_negative_x: not x_a.is_negative + do + x := x_a + end + +feature -- Field element components + + multZModF (a: INTEGER_X; m_limb_position: INTEGER m_bit_position: INTEGER k1_limb_position: INTEGER k1_bit_position: INTEGER) + require + a.is_positive + local + special: SPECIAL [NATURAL_32] + limb: NATURAL_32 + do + a.bit_shift_left (1) + special := a.item + limb := special [m_limb_position] + if + limb.bit_test (m_bit_position) + then + special [m_limb_position] := limb.set_bit (False, m_bit_position) + special [0] := special [0].bit_xor (1) + special [k1_limb_position] := special [k1_limb_position].bit_xor ((1).to_natural_32 |<< k1_bit_position) + end + ensure + a.is_positive + end + + + multZModF_p (a: INTEGER_X; m_limb_position: INTEGER m_bit_position: INTEGER k1_limb_position: INTEGER k1_bit_position: INTEGER k2_limb_position: INTEGER k2_bit_position: INTEGER k3_limb_position: INTEGER k3_bit_position: INTEGER) + require + a.is_positive + local + special: SPECIAL [NATURAL_32] + limb: NATURAL_32 + do + a.bit_shift_left (1) + special := a.item + limb := special [m_limb_position] + if + limb.bit_test (m_bit_position) + then + special [m_limb_position] := limb.set_bit (False, m_bit_position) + special [0] := special [0].bit_xor (1) + special [k1_limb_position] := special [k1_limb_position].bit_xor ((1).to_natural_32 |<< k1_bit_position) + special [k2_limb_position] := special [k2_limb_position].bit_xor ((1).to_natural_32 |<< k2_bit_position) + special [k3_limb_position] := special [k3_limb_position].bit_xor ((1).to_natural_32 |<< k3_bit_position) + end + ensure + a.is_positive + end + +feature + + encoded_field_size (curve: EC_CURVE_F2M): INTEGER_32 + -- + obsolete + "Needs implementation" + do + + end + +feature -- Implementing features of ECFIELDELEMENT + + plus_value (other: like Current; curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (other, curve) + end + + plus (other: like Current; curve: EC_CURVE_F2M) + do + x.bit_xor (other.x) + end + + minus_value (other: like Current; curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (other, curve) + end + + minus (other: like Current; curve: EC_CURVE_F2M) + do + plus (other, curve) + end + + product_value (b: like Current; curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (b, curve) + end + + product (b: like Current; curve: EC_CURVE_F2M) + local + m: INTEGER + m_bit_position: INTEGER + m_limb_position: INTEGER + k1_bit_position: INTEGER + k1_limb_position: INTEGER + k2_bit_position: INTEGER + k2_limb_position: INTEGER + k3_bit_position: INTEGER + k3_limb_position: INTEGER + bz: INTEGER_X + cz: INTEGER_X + special: SPECIAL [NATURAL_32] + limb: NATURAL_32 + limb_position: INTEGER + bit_position: INTEGER + new_bit_position: INTEGER + do + m := curve.m + m_limb_position := bit_index_to_limb_index (m) + m_bit_position := m \\ limb_bits + k1_limb_position := bit_index_to_limb_index (curve.k1) + k1_bit_position := curve.k1 \\ limb_bits + k2_limb_position := bit_index_to_limb_index (curve.k2) + k2_bit_position := curve.k2 \\ limb_bits + k3_limb_position := bit_index_to_limb_index (curve.k3) + k3_bit_position := curve.k3 \\ limb_bits + create bz.make_bits (m + m) + bz.copy (b.x) + limb_position := 0 + bit_position := 0 + special := x.item + x.resize (bits_to_limbs (m)) + limb := special [limb_position] + create cz.make_bits (m + m) + from + bit_position := 0 + until + limb_position * limb_bits + bit_position >= m + loop + if + limb.bit_test (bit_position) + then + cz.bit_xor (bz) + end + new_bit_position := (bit_position + 1) \\ limb_bits + if new_bit_position < bit_position then + limb_position := limb_position + 1 + limb := special [limb_position] + end + bit_position := new_bit_position + if curve.representation = PPB then + multZmodF_p (bz, m_limb_position, m_bit_position, k1_limb_position, k1_bit_position, k2_limb_position, k2_bit_position, k3_limb_position, k3_bit_position) + else + multZmodF (bz, m_limb_position, m_bit_position, k1_limb_position, k1_bit_position) + end + end + x := cz + end + + quotient_value (other: like Current; curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (other, curve) + end + + quotient (other: like Current; curve: EC_CURVE_F2M) + local + bInv: like Current + do + bInv := other.inverse_value (curve) + product (bInv, curve) + end + + opposite_value (curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (curve) + end + + opposite (curve: EC_CURVE_F2M) + do + do_nothing + end + + square_value (curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (curve) + end + + square (curve: EC_CURVE_F2M) + local + i: INTEGER_32 + limb_position: INTEGER + bit_position: INTEGER + new_bit_position: INTEGER + square_limb_position: INTEGER + square_bit_position: INTEGER + limb: NATURAL_32 + square_limb: NATURAL_32 + special: SPECIAL [NATURAL_32] + do + from + i := curve.m + x.resize (bits_to_limbs (i + i)) + special := x.item + limb_position := bit_index_to_limb_index (i) + bit_position := i \\ limb_bits + square_limb_position := bit_index_to_limb_index (i + i) + square_bit_position := (i + i) \\ limb_bits + limb := special [limb_position] + square_limb := special [square_limb_position] + invariant + i = limb_position * limb_bits + bit_position + until + i < 0 + loop + if + limb.bit_test (bit_position) + then +-- x.set_bit (True, i + i) + square_limb := square_limb.set_bit (True, square_bit_position) + else +-- x.set_bit (False, i + i) + square_limb := square_limb.set_bit (False, square_bit_position) + end +-- x.set_bit (False, i + i + 1) + square_limb := square_limb.set_bit (False, square_bit_position + 1) + new_bit_position := bit_position - 1 + if new_bit_position < 0 and limb_position > 0 then + new_bit_position := new_bit_position + limb_bits + limb_position := limb_position - 1 + limb := special [limb_position] + end + bit_position := new_bit_position + new_bit_position := square_bit_position - 2 + if new_bit_position < 0 and square_limb_position > 0 then + new_bit_position := new_bit_position + limb_bits + special [square_limb_position] := square_limb + square_limb_position := square_limb_position - 1 + square_limb := special [square_limb_position] + end + square_bit_position := new_bit_position + i := i - 1 + variant + i + 3 + end + if square_bit_position /= limb_bits - 2 then + special [square_limb_position] := square_limb + else + do_nothing + end + reduce (x, curve) + x.count := x.normalize (special, 0, bits_to_limbs (curve.m)) + end + + reduce (in: INTEGER_X; curve: EC_CURVE_F2M) + local + m: INTEGER + i: INTEGER + k1: INTEGER + k1_limb_position: INTEGER + k1_limb_diff: NATURAL_32 + k1_bit_position: INTEGER + k2: INTEGER + k2_limb_position: INTEGER + k2_limb_diff: NATURAL_32 + k2_bit_position: INTEGER + k3: INTEGER + k3_limb_position: INTEGER + k3_limb_diff: NATURAL_32 + k3_bit_position: INTEGER + low_limb_position: INTEGER + low_limb_diff: NATURAL_32 + low_bit_position: INTEGER + special: SPECIAL [NATURAL_32] + limb: NATURAL_32 + limb_diff: NATURAL_32 + limb_position: INTEGER + bit_position: INTEGER + new_bit_position: INTEGER + do + m := curve.m + k1 := curve.k1 + k2 := curve.k2 + k3 := curve.k3 + special := in.item + from + i := m + m - 1 + limb_position := bit_index_to_limb_index (i) + low_limb_position := bit_index_to_limb_index (i - m) + k1_limb_position := bit_index_to_limb_index (k1 + i - m) + bit_position := i \\ limb_bits + low_bit_position := (i - m) \\ limb_bits + k1_bit_position := (k1 + i - m) \\ limb_bits + if curve.representation = PPB then + k2_limb_position := bit_index_to_limb_index (k2 + i - m) + k3_limb_position := bit_index_to_limb_index (k3 + i - m) + k2_bit_position := (k2 + i - m) \\ limb_bits + k3_bit_position := (k3 + i - m) \\ limb_bits + end + limb := special [limb_position] + invariant + i = limb_position * limb_bits + bit_position + until + i < m + loop + if + limb.bit_test (bit_position) + then + limb_diff := limb_diff.set_bit (True, bit_position) + low_limb_diff := low_limb_diff.set_bit (True, low_bit_position) + k1_limb_diff := k1_limb_diff.set_bit (True, k1_bit_position) + if + curve.representation = PPB + then + k2_limb_diff := k2_limb_diff.set_bit (True, k2_bit_position) + k3_limb_diff := k3_limb_diff.set_bit (True, k3_bit_position) + end + end + new_bit_position := bit_position - 1 + if new_bit_position < 0 then + new_bit_position := new_bit_position + limb_bits + special [limb_position] := special [limb_position].bit_xor (limb_diff) + limb_position := limb_position - 1 + limb := special [limb_position] + limb_diff := 0 + end + bit_position := new_bit_position + new_bit_position := low_bit_position - 1 + if new_bit_position < 0 then + new_bit_position := new_bit_position + limb_bits + special [low_limb_position] := special [low_limb_position].bit_xor (low_limb_diff) + low_limb_position := low_limb_position - 1 + low_limb_diff := 0 + end + low_bit_position := new_bit_position + new_bit_position := k1_bit_position - 1 + if new_bit_position < 0 then + new_bit_position := new_bit_position + limb_bits + special [k1_limb_position] := special [k1_limb_position].bit_xor (k1_limb_diff) + k1_limb_position := k1_limb_position - 1 + k1_limb_diff := 0 + end + k1_bit_position := new_bit_position + if curve.representation = PPB then + new_bit_position := k2_bit_position - 1 + if new_bit_position < 0 then + new_bit_position := new_bit_position + limb_bits + special [k2_limb_position] := special [k2_limb_position].bit_xor (k2_limb_diff) + k2_limb_position := k2_limb_position - 1 + k2_limb_diff := 0 + end + k2_bit_position := new_bit_position + new_bit_position := k3_bit_position - 1 + if new_bit_position < 0 then + new_bit_position := new_bit_position + limb_bits + special [k3_limb_position] := special [k3_limb_position].bit_xor (k3_limb_diff) + k3_limb_position := k3_limb_position - 1 + k3_limb_diff := 0 + end + k3_bit_position := new_bit_position + end + i := i - 1 + end + if bit_position /= limb_bits - 1 then + special [limb_position] := special [limb_position].bit_xor (limb_diff) + end + if low_bit_position /= limb_bits - 1 then + special [low_limb_position] := special [low_limb_position].bit_xor (low_limb_diff) + end + if k1_bit_position /= limb_bits - 1 then + special [k1_limb_position] := special [k1_limb_position].bit_xor (k1_limb_diff) + end + if curve.representation = PPB then + if k2_bit_position /= limb_bits - 1 then + special [k2_limb_position] := special [k2_limb_position].bit_xor (k2_limb_diff) + end + if k3_bit_position /= limb_bits - 1 then + special [k3_limb_position] := special [k3_limb_position].bit_xor (k3_limb_diff) + end + end + in.count := in.normalize (special, 0, in.count) + end + + inverse_value (curve: EC_CURVE_F2M): EC_FIELD_ELEMENT_F2M + do + Result := Precursor (curve) + end + + inverse (curve: EC_CURVE_F2M) + local + uz: INTEGER_X + vz: INTEGER_X +-- g1z: INTEGER_X +-- g2z: INTEGER_X +-- j: INTEGER_32 +-- tmp_int: INTEGER_X + m: INTEGER +-- uz_bits: INTEGER +-- vz_bits: INTEGER +-- tmp_int2: INTEGER +-- uz_old: INTEGER_X +-- gz_old: INTEGER_X + do + m := curve.m + create uz.make_bits (m + m) + uz.copy (x) + create vz.make_bits (m + m) + vz.set_bit (True, m) + vz.set_bit (True, 0) + vz.set_bit (True, curve.k1) + if + curve.representation = PPB + then + vz.set_bit (True, curve.k2) + vz.set_bit (True, curve.k3) + end + vz.count := normalize (vz.item, 0, bits_to_limbs (m)) + + x.invert_gf (vz) +-- create g1z.make_bits (m + m) +-- g1z.set_from_integer (1) +-- create g2z.make_bits (m + m) +-- from +-- until +-- uz.is_zero +-- loop +-- uz_bits := uz.bits +-- vz_bits := vz.bits +-- if +-- uz_bits < vz_bits +-- then +-- tmp_int := uz +-- uz := vz +-- vz := tmp_int +-- tmp_int := g1z +-- g1z := g2z +-- g2z := tmp_int +-- tmp_int2 := uz_bits +-- uz_bits := vz_bits +-- vz_bits := tmp_int2 +-- end +-- if uz_bits /= vz_bits then +-- j := uz_bits - vz_bits +---- vz.bit_shift_left (j) +---- uz_old := uz.bit_xor_value (vz) +---- vz.bit_shift_right (j) +---- g2z.bit_shift_left (j) +---- gz_old := g1z.bit_xor_value (g2z) +---- g2z.bit_shift_right (j) +-- uz.bit_xor_left_shift (vz, j) +-- g1z.bit_xor_left_shift (g2z, j) +-- else +-- uz.bit_xor (vz) +-- g1z.bit_xor (g2z) +-- end +-- end +-- x := g2z + end + + sqrt (curve: EC_CURVE_F2M): like Current + -- Not implemented + do + create Result.make (create {INTEGER_X}.default_create) + end + + is_equal (other: like Current): BOOLEAN + do + Result := x ~ other.x + end + +end diff --git a/library/crypto/eel/ec/ec_field_element_fp.e b/library/crypto/eel/ec/ec_field_element_fp.e new file mode 100644 index 00000000..4e782275 --- /dev/null +++ b/library/crypto/eel/ec/ec_field_element_fp.e @@ -0,0 +1,214 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Liberty lies in the hearts of men and women. When it dies there, no constitution, no law, no court can save it. - Justice Learned Hand" + +class + EC_FIELD_ELEMENT_FP + +inherit + EC_FIELD_ELEMENT + redefine + is_equal, + plus_value, + minus_value, + product_value, + quotient_value, + opposite_value, + square_value, + inverse_value + end + +create + make_p_x, + make_q_x_hex + +create {EC_POINT, EC_CURVE_FP} + make_zero + +feature {EC_POINT_FP, EC_CURVE_FP} + make_zero + do + create x.default_create + end + +feature + make_p_x (x_new: INTEGER_X) + -- create a new ECFIELDELEMENTFP based on q and x + do + x := x_new + end + + make_q_x_hex(curve_a: EC_CURVE_FP x_hex_a: STRING) + do + make_p_x (create {INTEGER_X}.make_from_hex_string (x_hex_a)) + end + +feature {EC_FIELD_ELEMENT_FP} + + W (n: INTEGER_X r: INTEGER_X x_new: INTEGER_X p_a: INTEGER_X): INTEGER_X + -- I'm not sure what this does + local + w_one: INTEGER_X + w_two: INTEGER_X + do + if + n ~ (ONE) + then + result := ((r * r * x_new.powm_value ((p_a - TWO), p_a)) - TWO) \\ p_a + elseif + not n.bit_test(0) + then + w_one := W (n / TWO, r, x, p_a) + result := ((w_one * w_one) - TWO) \\ p_a + else + w_one := W ((n + ONE) / TWO, r, x, p_a) + w_two := W ((n - ONE) / TWO, r, x, p_a) + result := ((w_one * w_two) - W (ONE, r, x, p_a)) \\ p_a + end + end + +feature + encoded_field_size (curve: EC_CURVE_FP): INTEGER_32 + -- Return the encoded field size for FP field elements + local + p: INTEGER_X + do + p := curve.q + result := p.bytes + end + + plus_value (other: like Current; curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (other, curve) + end + + plus (other: like Current; curve: EC_CURVE_FP) + do + x.plus (other.x) + x.modulo (curve.q) + end + + minus_value (other: like Current; curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (other, curve) + end + + minus (other: like Current; curve: EC_CURVE_FP) + do + x.minus (other.x) + x.modulo (curve.q) + end + + product_value (other: like Current; curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (other, curve) + end + + product (other: like Current; curve: EC_CURVE_FP) + do + x.product (other.x) + x.modulo (curve.q) + end + + quotient_value (other: like Current; curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (other, curve) + end + + quotient (other: like Current; curve: EC_CURVE_FP) + local + p: INTEGER_X + do + p := curve.q + x.product (other.x.inverse_value (p)) + x.modulo (p) + end + + opposite_value (curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (curve) + end + + opposite (curve: EC_CURVE_FP) + do + x.opposite + x.modulo (curve.q) + end + + square_value (curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (curve) + end + + square (curve: EC_CURVE_FP) + do + x.product (x) + x.modulo (curve.q) + end + + inverse_value (curve: EC_CURVE_FP): EC_FIELD_ELEMENT_FP + do + Result := Precursor (curve) + end + + inverse (curve: EC_CURVE_FP) + do + x.inverse (curve.q) + end + + sqrt (curve: EC_CURVE_FP): like Current + -- Implement sqrt over FP + local + z: EC_FIELD_ELEMENT_FP + legendreExponent: INTEGER_X + fourX: INTEGER_X + r: INTEGER_X + n1: INTEGER_X + n2: INTEGER_X + root: INTEGER_X + exponent: INTEGER_X + p: INTEGER_X + do + p := curve.q + if + p.bit_test (1) + then + create z.make_p_x (x.powm_value (p.bit_shift_right_value (2) + one, p)) + Result := z + elseif + p.bit_test (0) + then + legendreExponent := (p - ONE) / TWO + exponent := x.powm_value (legendreExponent, p) + check exponent ~ one end + fourX := FOUR * x + r := TWO + from + until + not ((r * r - fourx).powm_value (legendreExponent, p) ~ (p - ONE)) + loop + --Is this correct? There's a slightly higher chance that the + -- number is in the range 0 - q than q - 2^q.bits + create r.make_random (p.bits) + r := r \\ p + end + n1 := (p - ONE) / FOUR + n2 := (p + THREE) / FOUR + root := (x * (TWO * r).powm_value (p - TWO, p) * (W (n1, r, x, p) + W (n2, r, x, p))) \\ p + create z.make_p_x (root) + Result := z + else + create Result.make_p_x (create {INTEGER_X}.default_create) + (create {EXCEPTION}.default_create).raise + end + end + + is_equal (other: like current): BOOLEAN + -- Is this FP = other + do + result := x ~ other.x + end +end diff --git a/library/crypto/eel/ec/ec_key_pair.e b/library/crypto/eel/ec/ec_key_pair.e new file mode 100644 index 00000000..4798122b --- /dev/null +++ b/library/crypto/eel/ec/ec_key_pair.e @@ -0,0 +1,334 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "A nation of sheep will beget a government of wolves. - Edward R. Murrow" + +class + EC_KEY_PAIR + +inherit + DEBUG_OUTPUT + +create + make, + make_p192, + make_p224, + make_p256, + make_p384, + make_p521, + make_k163, + make_k233, + make_k283, + make_k409, + make_k571, + make_b163, + make_b233, + make_b283, + make_b409, + make_b571, + make_sec_p112r1, + make_sec_p112r2, + make_sec_p128r1, + make_sec_p128r2, + make_sec_p160k1, + make_sec_p160r1, + make_sec_p160r2, + make_sec_p192k1, + make_sec_p192r1, + make_sec_p224k1, + make_sec_p224r1, + make_sec_p256k1, + make_sec_p256r1, + make_sec_p384r1, + make_sec_p521r1, + make_sec_t113r1, + make_sec_t113r2, + make_sec_t131r1, + make_sec_t131r2, + make_sec_t163k1, + make_sec_t163r1, + make_sec_t163r2, + make_sec_t193r1, + make_sec_t193r2, + make_sec_t233k1, + make_sec_t233r1, + make_sec_t239k1, + make_sec_t283k1, + make_sec_t283r1, + make_sec_t409k1, + make_sec_t409r1, + make_sec_t571k1, + make_sec_t571r1 + +feature + make (params: EC_DOMAIN_PARAMETERS) + local + d: INTEGER_X + q: EC_POINT + do + from + create d.make_random_max (params.n) + until + not d.is_zero + loop + create d.make_random_max (params.n) + end + q := params.g.product_value (d, params.curve) + create public.make_q_parameters (q, params) + create private.make_d_params (d, params) + end + +feature --SEC recommended prime curves + make_sec_p112r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p112r1) + end + + make_sec_p112r2 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p112r2) + end + + make_sec_p128r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p128r1) + end + + make_sec_p128r2 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p128r2) + end + + make_sec_p160k1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p160k1) + end + + make_sec_p160r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p160r1) + end + + make_sec_p160r2 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p160r2) + end + + make_sec_p192k1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p192k1) + end + + make_sec_p192r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p192r1) + end + + make_sec_p224k1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p224k1) + end + + make_sec_p224r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p224r1) + end + + make_sec_p256k1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p256k1) + end + + make_sec_p256r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p256r1) + end + + make_sec_p384r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p384r1) + end + + make_sec_p521r1 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_sec_p521r1) + end + +feature --SEC recommended polynomial curves + make_sec_t113r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t113r1) + end + + make_sec_t113r2 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t113r2) + end + + make_sec_t131r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t131r1) + end + + make_sec_t131r2 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t131r2) + end + + make_sec_t163k1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t163k1) + end + + make_sec_t163r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t163r1) + end + + make_sec_t163r2 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t163r2) + end + + make_sec_t193r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t193r1) + end + + make_sec_t193r2 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t193r2) + end + + make_sec_t233k1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t233k1) + end + + make_sec_t233r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t233r1) + end + + make_sec_t239k1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t239k1) + end + + make_sec_t283k1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t283k1) + end + + make_sec_t283r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t283r1) + end + + make_sec_t409k1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t409k1) + end + + make_sec_t409r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t409r1) + end + + make_sec_t571k1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t571k1) + end + + make_sec_t571r1 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_sec_t571r1) + end + +feature --FIPS curves + make_p192 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_p192) + end + + make_p224 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_p224) + end + + make_p256 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_p256) + end + + make_p384 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_p384) + end + + make_p521 + do + make (create {EC_DOMAIN_PARAMETERS_FP}.make_p521) + end + + make_k163 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_k163) + end + + make_k233 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_k233) + end + + make_k283 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_k283) + end + + make_k409 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_k409) + end + + make_k571 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_k571) + end + + make_b163 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_b163) + end + + make_b233 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_b233) + end + + make_b283 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_b283) + end + + make_b409 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_b409) + end + + make_b571 + do + make (create {EC_DOMAIN_PARAMETERS_F2M}.make_b571) + end + + public: EC_PUBLIC_KEY + private: EC_PRIVATE_KEY + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := "Public:%N" + public.debug_output + "%NPrivate:%N" + private.debug_output + end +end diff --git a/library/crypto/eel/ec/ec_key_parameters.e b/library/crypto/eel/ec/ec_key_parameters.e new file mode 100644 index 00000000..01b02c28 --- /dev/null +++ b/library/crypto/eel/ec/ec_key_parameters.e @@ -0,0 +1,13 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "It is not the responsibility of the government or the legal system to protect a citizen from himself. - Justice Casey Percell" + +deferred class + EC_KEY_PARAMETERS + +feature + params: EC_DOMAIN_PARAMETERS +end diff --git a/library/crypto/eel/ec/ec_point.e b/library/crypto/eel/ec/ec_point.e new file mode 100644 index 00000000..6ac2f9f4 --- /dev/null +++ b/library/crypto/eel/ec/ec_point.e @@ -0,0 +1,122 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The government was set to protect man from criminals - and the Constitution was written to protect man from the government. - Ayn Rand" + +deferred class + EC_POINT + +inherit + ANY + redefine + is_equal + end + DEBUG_OUTPUT + undefine + is_equal + end + +feature + x: EC_FIELD_ELEMENT + y: EC_FIELD_ELEMENT + infinity: BOOLEAN + + make_infinity + deferred + ensure + infinity + end + + set_infinity + deferred + ensure + infinity + end + + is_equal (other: like Current): BOOLEAN + -- Is current point equal to other point + do + result := (infinity = other.infinity) and then (not infinity implies (x ~ other.x and y ~ other.y)) + end + + to_byte_array_compressed (curve: EC_CURVE): SPECIAL[NATURAL_8] + -- Return the Uncompressed version of this point, regardless of the creation + deferred + end + + to_byte_array_uncompressed (curve: EC_CURVE): SPECIAL[NATURAL_8] + -- Return the compressed version of this point + deferred + end + + plus (other: like Current curve: EC_CURVE) + deferred + end + + plus_value (other: like Current curve: EC_CURVE): like Current + do + Result := deep_twin + Result.plus (other, curve) + ensure + infinity implies Result ~ other + other.infinity implies Result ~ Current + (Current ~ other) implies (Result ~ twice_value (curve)) + end + + minus (other: like Current curve: EC_CURVE) + deferred + end + + minus_value (other: like Current curve: EC_CURVE): like Current + do + Result := deep_twin + Result.minus (other, curve) + ensure + infinity implies Result ~ other + other.infinity implies Result ~ Current + end + + twice (curve: EC_CURVE) + deferred + end + + twice_value (curve:EC_CURVE): like Current + do + Result := deep_twin + Result.twice (curve) + ensure + twice_definition: Result ~ Current.plus_value (Current, curve) + end + + product (other: INTEGER_X; curve: EC_CURVE) + deferred + end + + product_value (other: INTEGER_X; curve: EC_CURVE): like Current + do + Result := deep_twin + Result.product (other, curve) + end + + opposite (curve: EC_CURVE) + deferred + end + + opposite_value (curve: EC_CURVE): like Current + do + Result := deep_twin + Result.opposite (curve) + end + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := "0x" + x.debug_output + "%N0x" + y.debug_output + end + +invariant + infinity_x: infinity implies x.x.is_zero + infinity_y: infinity implies y.x.is_zero +end diff --git a/library/crypto/eel/ec/ec_point_f2m.e b/library/crypto/eel/ec/ec_point_f2m.e new file mode 100644 index 00000000..d7892ee9 --- /dev/null +++ b/library/crypto/eel/ec/ec_point_f2m.e @@ -0,0 +1,593 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "What this country needs are more unemployed politicians. - Edward Langley" + +class + EC_POINT_F2M + +inherit + EC_POINT + redefine + x, + y, + opposite_value, + twice_value, + product_value, + minus_value, + plus_value + end + EC_CONSTANTS + undefine + is_equal + end + STANDARD_CURVES + undefine + is_equal + end + INTEGER_X_FACILITIES + undefine + is_equal + end + +create + make_curve_x_y, + make_infinity, + make_from_bytes, + make_sec_t113r1, + make_sec_t113r2, + make_sec_t131r1, + make_sec_t131r2, + make_sec_t163k1, + make_sec_t163r1, + make_sec_t163r2, + make_sec_t193r1, + make_sec_t193r2, + make_sec_t233k1, + make_sec_t233r1, + make_sec_t239k1, + make_sec_t283k1, + make_sec_t283r1, + make_sec_t409k1, + make_sec_t409r1, + make_sec_t571k1, + make_sec_t571r1, + make_k163, + make_k233, + make_k283, + make_k409, + make_k571, + make_b163, + make_b233, + make_b283, + make_b409, + make_b571 + +feature + make_infinity + do + set_infinity + end + +feature -- SEC points + make_sec_t113r1 + do + create x.make (sec_t113r1_gx) + create y.make (sec_t113r1_gy) + end + + make_sec_t113r2 + do + create x.make (sec_t113r2_gx) + create y.make (sec_t113r2_gy) + end + + make_sec_t131r1 + do + create x.make (sec_t131r1_gx) + create y.make (sec_t131r1_gy) + end + + make_sec_t131r2 + do + create x.make (sec_t131r2_gx) + create y.make (sec_t131r2_gy) + end + + make_sec_t163k1 + do + create x.make (sec_t163k1_gx) + create y.make (sec_t163k1_gy) + end + + make_sec_t163r1 + do + create x.make (sec_t163r1_gx) + create y.make (sec_t163r1_gy) + end + + make_sec_t163r2 + do + create x.make (sec_t163r2_gx) + create y.make (sec_t163r2_gy) + end + + make_sec_t193r1 + do + create x.make (sec_t193r1_gx) + create y.make (sec_t193r1_gy) + end + + make_sec_t193r2 + do + create x.make (sec_t193r2_gx) + create y.make (sec_t193r2_gy) + end + + make_sec_t233k1 + do + create x.make (sec_t233k1_gx) + create y.make (sec_t233k1_gy) + end + + make_sec_t233r1 + do + create x.make (sec_t233r1_gx) + create y.make (sec_t233r1_gy) + end + + make_sec_t239k1 + do + create x.make (sec_t239k1_gx) + create y.make (sec_t239k1_gy) + end + + make_sec_t283k1 + do + create x.make (sec_t283k1_gx) + create y.make (sec_t283k1_gy) + end + + make_sec_t283r1 + do + create x.make (sec_t283r1_gx) + create y.make (sec_t283r1_gy) + end + + make_sec_t409k1 + do + create x.make (sec_t409k1_gx) + create y.make (sec_t409k1_gy) + end + + make_sec_t409r1 + do + create x.make (sec_t409r1_gx) + create y.make (sec_t409r1_gy) + end + + make_sec_t571k1 + do + create x.make (sec_t571k1_gx) + create y.make (sec_t571k1_gy) + end + + make_sec_t571r1 + do + create x.make (sec_t571r1_gx) + create y.make (sec_t571r1_gy) + end + +feature -- FIPS points + make_k163 + do + create x.make (k163_gx) + create y.make (k163_gy) + end + + make_k233 + do + create x.make (k233_gx) + create y.make (k233_gy) + end + + make_k283 + do + create x.make (k283_gx) + create y.make (k283_gy) + end + + make_k409 + do + create x.make (k409_gx) + create y.make (k409_gy) + end + + make_k571 + do + create x.make (k571_gx) + create y.make (k571_gy) + end + + make_b163 + do + create x.make (b163_gx) + create y.make (b163_gy) + end + + make_b233 + do + create x.make (b233_gx) + create y.make (b233_gy) + end + + make_b283 + do + create x.make (b283_gx) + create y.make (b283_gy) + end + + make_b409 + do + create x.make (b409_gx) + create y.make (b409_gy) + end + + make_b571 + do + create x.make (b571_gx) + create y.make (b571_gy) + end + + make_curve_x_y (x_a: EC_FIELD_ELEMENT_F2M; y_a: EC_FIELD_ELEMENT_F2M) + do + x := x_a + y := y_a + end + + make_from_bytes (bytes: SPECIAL[NATURAL_8]; curve: EC_CURVE_F2M) + do + decodepoint (bytes, curve) + end + +feature + + x: EC_FIELD_ELEMENT_F2M + y: EC_FIELD_ELEMENT_F2M + + set_from_other (other: like Current) + do + x.copy (other.x) + y.copy (other.y) + end + +feature -- Decode/encode + + set_infinity + do + create x.make (create {INTEGER_X}.default_create) + create y.make (create {INTEGER_X}.default_create) + infinity := True + end + + decodePoint (source: SPECIAL [NATURAL_8] curve: EC_CURVE_F2M) + require + Source_too_small: source.capacity > 0 + local + enc: SPECIAL [NATURAL_8] + do + create enc.make_filled (0, source.count - 1) + enc.copy_data (source, 1, 0, enc.count) + inspect + source[0] + when 0x02 then + decodeCompressedPoint (enc, 0, curve) + when 0x03 then + decodeCompressedPoint (enc, 1, curve) + when 0x04 then + decodeUncompressedPoint (enc) + end + end + + decodeCompressedPoint (source: SPECIAL [NATURAL_8] ypBit: INTEGER curve: EC_CURVE_F2M) + local + xp: EC_FIELD_ELEMENT_F2M + yp: EC_FIELD_ELEMENT_F2M + i: INTEGER_32 + beta: EC_FIELD_ELEMENT_F2M + z: EC_FIELD_ELEMENT_F2M + oneEC: EC_FIELD_ELEMENT_F2M + zBit: INTEGER + do + create xp.make (create {INTEGER_X}.make_from_bytes (source, source.lower, source.upper)) + if + xp.x.is_zero + then + yp := curve.b + from + i := 0 + until + i = curve.m - 1 + loop + yp := yp.square_value (curve) + i := i + 1 + end + else + beta := xp.plus_value (curve.a, curve).plus_value (curve.b.product_value (xp.square_value (curve).inverse_value (curve), curve), curve) + --z := solveQuadraticEquation(beta) + create z.make (create {INTEGER_X}.default_create) + zBit := 0 + if + z.x.bit_test (0) + then + zBit := 1 + end + if + zBit /= ypBit + then + create oneEC.make (ONE) + z := z.plus_value (oneEC, curve) + end + yp := xp.product_value (z, curve) + end + x := xp + y := yp + end + + decodeUncompressedPoint (source: SPECIAL [NATURAL_8]) + require + X_and_y_different_sizes: source.capacity \\ 2 = 0 + local + xEnc: SPECIAL [NATURAL_8] + yEnc: SPECIAL [NATURAL_8] + x_mpz: INTEGER_X + y_mpz: INTEGER_X + do + create xEnc.make_filled (0, source.count // 2) + xEnc.copy_data (source, 0, 0, xEnc.count) + create yEnc.make_filled (0, source.count // 2) + yEnc.copy_data (source, source.count // 2, 0, yEnc.count) + check -- Field elements should be same size + xEnc.capacity = yEnc.capacity + end + create x_mpz.make_from_bytes (xEnc, xEnc.lower, xEnc.upper) + create y_mpz.make_from_bytes (yEnc, yEnc.lower, yEnc.upper) + create x.make (x_mpz) + create y.make (y_mpz) + end + + to_byte_array_uncompressed (curve: EC_CURVE_F2M): SPECIAL [NATURAL_8] + local + byteCount: INTEGER_32 + y_array: SPECIAL [NATURAL_8] + x_array: SPECIAL [NATURAL_8] + p0: SPECIAL [NATURAL_8] + do + bytecount := x.x.bytes + x_array := x.x.as_bytes + y_array := y.x.as_fixed_width_byte_array (byteCount) + create p0.make_filled (0, byteCount + byteCount + 1) + p0.put (0x04, 0) + check + x_array.capacity = y_array.capacity + end + p0.copy_data (x_array, 0, x_array.upper, 1) + p0.copy_data (y_array, 0, y_array.upper, x_array.upper + 1) + result := p0 + end + + to_byte_array_compressed (curve: EC_CURVE_F2M): SPECIAL [NATURAL_8] + local + byteCount: INTEGER_32 + x_array: SPECIAL [NATURAL_8] + P0: SPECIAL [NATURAL_8] + do + x_array := x.x.as_bytes + byteCount := x.x.bytes + -- See X9.62 4.3.6 and 4.2.2 + create P0.make_filled (0, byteCount + 1) + p0.put (0x02, 0) + + -- X9.62 4.2.2 and 4.3.6: + -- if x = 0 then ypTilde := 0, else ypTilde is the rightmost + -- bit of y * x^(-1) + -- if ypTilde = 0, then PC := 02, else PC := 03 + -- Note: PC === PO[0] + if + (not (x.x.is_zero)) and ((y.product_value (x.inverse_value (curve), curve)).x.bit_test(0)) + then + -- ypTilde = 1, hence PC = 03 + p0.put (0x03, 0) + end + p0.copy_data (x_array, 0, x_array.upper, 1) + result := p0 + end + +feature -- Implement ECPOINT + + plus_value (other: like Current; curve: EC_CURVE_F2M): EC_POINT_F2M + do + Result := Precursor (other, curve) + end + + plus (other: like Current; curve: EC_CURVE_F2M) + do + if + infinity + then + copy (other) + elseif + other.infinity + then + + else + add_not_infinity (other, curve) + end + end + + minus_value (other: like Current; curve: EC_CURVE_F2M): EC_POINT_F2M + do + Result := Precursor (other, curve) + end + + minus (other: like Current; curve: EC_CURVE_F2M) + do + if + other.infinity + then + else + add_minus_b (other, curve) + end + end + + product_value (b: INTEGER_X; curve: EC_CURVE_F2M): EC_POINT_F2M + do + Result := Precursor (b, curve) + end + + product (b: INTEGER_X; curve: EC_CURVE_F2M) + local + p: like Current + q: like Current + t: INTEGER_32 +-- i: INTEGER_32 + special: SPECIAL [NATURAL_32] + limb: NATURAL_32 + limb_position: INTEGER + new_bit_position: INTEGER + bit_position: INTEGER + do + p := Current + create q.make_infinity + t := b.bits + from + special := b.item + limb := special [limb_position] + limb_position := 0 + bit_position := 0 + until + limb_position * 32 + bit_position >= t + loop + if limb.bit_test (bit_position) then + q.plus (p, curve) + end + p.twice (curve) + new_bit_position := (bit_position + 1) \\ 32 + if new_bit_position < bit_position then + limb_position := limb_position + 1 + limb := special [limb_position] + end + bit_position := new_bit_position + end +-- p := Current +-- create q.make_infinity +-- t := b.bits +-- from +-- i := 0 +-- until +-- i = t +-- loop +-- if +-- b.bit_test (i) +-- then +-- q.plus (p, curve) +-- end +-- p.twice (curve) +-- i := i + 1 +-- end + copy (q) + end + + twice_value (curve: EC_CURVE_F2M): EC_POINT_F2M + do + Result := Precursor (curve) + end + + twice (curve: EC_CURVE_F2M) + do + if + infinity + then + elseif + x.x.is_zero + then + set_infinity + else + twice_not_infinity (curve) + end + end + + opposite_value (curve: EC_CURVE_F2M): EC_POINT_F2M + do + Result := Precursor (curve) + end + + opposite (curve: EC_CURVE_F2M) + do + y.plus (x, curve) + end + +feature -- Implementation support features + + twice_not_infinity (curve: EC_CURVE_F2M) + local + lambda: EC_FIELD_ELEMENT_F2M + x3: EC_FIELD_ELEMENT_F2M + y3: EC_FIELD_ELEMENT_F2M + one_element: EC_FIELD_ELEMENT_F2M + do + create one_element.make (one) + lambda := y.quotient_value (x, curve) + lambda.plus (x, curve) + x3 := lambda.square_value (curve) + x3.plus (lambda, curve) + x3.plus (curve.a, curve) + y3 := x.square_value (curve) + lambda.plus (one_element, curve) + lambda.product (x3, curve) + y3.plus (lambda, curve) + x := x3 + y := y3 + end + + add_minus_b (other: like Current curve: EC_CURVE_F2M) + local + minusB: like Current + do + create minusB.make_curve_x_y (other.x, other.x.plus_value (other.y, curve)) + plus (minusB, curve) + end + + add_not_infinity (other: like Current; curve: EC_CURVE_F2M) + do + if + x ~ other.x + then + if + y ~ other.y + then + copy (twice_value (curve)) + else + set_infinity + end + else + add_normal (other, curve) + end + end + + add_normal (other: like Current; curve: EC_CURVE_F2M) + local + lambda: EC_FIELD_ELEMENT_F2M + x3: EC_FIELD_ELEMENT_F2M + y3: EC_FIELD_ELEMENT_F2M + do + lambda := (y.plus_value (other.y, curve)).quotient_value (x.plus_value (other.x, curve), curve) + x3 := lambda.square_value (curve) + x3 := x3.plus_value (lambda, curve).plus_value (x, curve).plus_value (other.x, curve).plus_value (curve.a, curve) + y3 := ((lambda.product_value (x.plus_value (x3, curve), curve)).plus_value (x3, curve)).plus_value (y, curve) + x := x3 + y := y3 + end +end diff --git a/library/crypto/eel/ec/ec_point_fp.e b/library/crypto/eel/ec/ec_point_fp.e new file mode 100644 index 00000000..af1d8b23 --- /dev/null +++ b/library/crypto/eel/ec/ec_point_fp.e @@ -0,0 +1,481 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Those who expect to reap the benefits of freedom, must, like men, undergo the fatigue of supporting it. - Thomas Paine" + +class + EC_POINT_FP + +inherit + EC_POINT + redefine + x, + y, + copy, + opposite_value, + product_value, + twice_value, + minus_value, + plus_value + end + EC_CONSTANTS + undefine + is_equal, + copy + end + STANDARD_CURVES + undefine + is_equal, + copy + end + +create + make_curve_x_y, + make_from_bytes, + make_infinity, + make_sec_p112r1, + make_sec_p112r2, + make_sec_p128r1, + make_sec_p128r2, + make_sec_p160k1, + make_sec_p160r1, + make_sec_p160r2, + make_sec_p192k1, + make_sec_p192r1, + make_sec_p224k1, + make_sec_p224r1, + make_sec_p256k1, + make_sec_p256r1, + make_sec_p384r1, + make_sec_p521r1, + make_p192, + make_p224, + make_p256, + make_p384, + make_p521 + +feature + make_infinity + do + set_infinity + end + +feature -- SEC curves + make_sec_p112r1 + do + create x.make_p_x (sec_p112r1_gx) + create y.make_p_x (sec_p112r1_gy) + end + + make_sec_p112r2 + do + create x.make_p_x (sec_p112r2_gx) + create y.make_p_x (sec_p112r2_gy) + end + + make_sec_p128r1 + do + create x.make_p_x (sec_p128r1_gx) + create y.make_p_x (sec_p128r1_gy) + end + + make_sec_p128r2 + do + create x.make_p_x (sec_p128r2_gx) + create y.make_p_x (sec_p128r2_gy) + end + + make_sec_p160k1 + do + create x.make_p_x (sec_p160k1_gx) + create y.make_p_x (sec_p160k1_gy) + end + + make_sec_p160r1 + do + create x.make_p_x (sec_p160r1_gx) + create y.make_p_x (sec_p160r1_gy) + end + + make_sec_p160r2 + do + create x.make_p_x (sec_p160r2_gx) + create y.make_p_x (sec_p160r2_gy) + end + + make_sec_p192k1 + do + create x.make_p_x (sec_p192k1_gx) + create y.make_p_x (sec_p192k1_gy) + end + + make_sec_p192r1 + do + create x.make_p_x (sec_p192r1_gx) + create y.make_p_x (sec_p192r1_gy) + end + + make_sec_p224k1 + do + create x.make_p_x (sec_p224k1_gx) + create y.make_p_x (sec_p224k1_gy) + end + + make_sec_p224r1 + do + create x.make_p_x (sec_p224r1_gx) + create y.make_p_x (sec_p224r1_gy) + end + + make_sec_p256k1 + do + create x.make_p_x (sec_p256k1_gx) + create y.make_p_x (sec_p256k1_gy) + end + + make_sec_p256r1 + do + create x.make_p_x (sec_p256r1_gx) + create y.make_p_x (sec_p256r1_gy) + end + + make_sec_p384r1 + do + create x.make_p_x (sec_p384r1_gx) + create y.make_p_x (sec_p384r1_gy) + end + + make_sec_p521r1 + do + create x.make_p_x (sec_p521r1_gx) + create y.make_p_x (sec_p521r1_gy) + end + +feature + make_p192 + do + create x.make_p_x (p192_gx) + create y.make_p_x (p192_gy) + end + + make_p224 + do + create x.make_p_x (p224_gx) + create y.make_p_x (p224_gy) + end + + make_p256 + do + create x.make_p_x (p256_gx) + create y.make_p_x (p256_gy) + end + + make_p384 + do + create x.make_p_x (p384_gx) + create y.make_p_x (p384_gy) + end + + make_p521 + do + create x.make_p_x (p521_gx) + create y.make_p_x (p521_gy) + end + + make_curve_x_y (x_a: EC_FIELD_ELEMENT_FP; y_a: EC_FIELD_ELEMENT_FP) + do + x := x_a + y := y_a + end + + make_from_bytes (encoded: SPECIAL [NATURAL_8] curve: EC_CURVE_FP) + -- Decode a point on this curve from its ASN.1 encoding + -- encodings are taken account of, including point compression for + -- Fp (X9.62 s 4.2.1 pg 17). + -- @return The decoded point. + require + first_byte_indicator: encoded [0] = 0x02 or encoded [0] = 0x3 or encoded [0] = 0x4 + do + inspect + encoded [0] + when 0x02 then + decodeCompressedPoint (encoded, 0, curve) + when 0x03 then + decodeCompressedPoint (encoded, 1, curve) + when 0x04 then + decodeUncompressedPoint (encoded) + end + end + +feature + x: EC_FIELD_ELEMENT_FP + y: EC_FIELD_ELEMENT_FP + + copy (other: like Current) + do + x.copy (other.x) + y.copy (other.y) + end + +feature + + set_infinity + do + create x.make_p_x (create {INTEGER_X}.default_create) + create y.make_p_x (create {INTEGER_X}.default_create) + infinity := True + end + + to_byte_array_compressed (curve: EC_CURVE_FP): SPECIAL [NATURAL_8] + -- Return a compressed encoded version of this point + local + x_array: SPECIAL [NATURAL_8] + do + x_array := x.x.as_fixed_width_byte_array (x.encoded_field_size (curve)) + create result.make_filled (0, x_array.count + 1) + result.copy_data (x_array, 0, 1, x_array.count) + result [0] := compressed_PC_byte (y.x) + end + + to_byte_array_uncompressed (curve: EC_CURVE_FP): SPECIAL [NATURAL_8] + -- Return an uncompressed encoded version of this point + local + x_array: SPECIAL [NATURAL_8] + y_array: SPECIAL [NATURAL_8] + p0: SPECIAL [NATURAL_8] + qLength: INTEGER_32 + do + qLength := x.encoded_field_size (curve) + x_array := x.x.as_fixed_width_byte_array (qlength) + y_array := y.x.as_fixed_width_byte_array (qLength) + check + x_array.capacity = qlength + y_array.capacity = qlength + end + create p0.make_filled (0, x_array.capacity + y_array.capacity + 1) + p0.copy_data (x_array, 0, x_array.upper, 1) + p0.copy_data (y_array, 0, y_array.upper, x_array.capacity + 1) + p0.put (0x04, 0) + result := p0 + end + + plus_value (other: like Current; curve: EC_CURVE_FP): EC_POINT_FP + do + Result := Precursor (other, curve) + end + + plus (other: like Current; curve: EC_CURVE_FP) + -- Addition over FP + local + gamma: EC_FIELD_ELEMENT_FP + x3: EC_FIELD_ELEMENT_FP + y3: EC_FIELD_ELEMENT_FP + do + if + infinity + then + copy (other) + elseif + other.infinity + then + elseif + x ~ other.x + then + if + y ~ other.y + then + copy (twice_value (curve)) + else + set_infinity + end + else + gamma := (other.y.minus_value (y, curve)).quotient_value (other.x.minus_value (x, curve), curve) + x3 := (gamma.product_value (gamma, curve)).minus_value (x, curve).minus_value (other.x, curve) + y3 := (gamma.product_value (x.minus_value (x3, curve), curve)).minus_value (y, curve) + x := x3 + y := y3 + end + end + + twice_value (curve: EC_CURVE_FP): EC_POINT_FP + do + Result := Precursor (curve) + end + + twice (curve: EC_CURVE_FP) + -- Return current * current over FP + local + two_element: EC_FIELD_ELEMENT_FP + three_element: EC_FIELD_ELEMENT_FP + gamma: EC_FIELD_ELEMENT_FP + x3: EC_FIELD_ELEMENT_FP + y3: EC_FIELD_ELEMENT_FP + do + if + infinity + then + elseif + y.x.is_zero + then + set_infinity + else + create two_element.make_p_x (two) + create three_element.make_p_x (three) + gamma := (((x.product_value (x, curve)).product_value (three_element, curve)).plus_value (curve.a, curve)).quotient_value (y.product_value (two_element, curve), curve) + x3 := (gamma.product_value (gamma, curve)).minus_value (x.product_value (two_element, curve), curve) + y3 := (gamma.product_value (x.minus_value (x3, curve), curve)).minus_value (y, curve) + x := x3 + y := y3 + end + end + + minus_value (other: like Current; curve: EC_CURVE_FP): EC_POINT_FP + do + Result := Precursor (other, curve) + end + + minus (other: like Current; curve: EC_CURVE_FP) + do + if + other.infinity + then + else + plus (other.opposite_value (curve), curve) + end + end + + product_value (other: INTEGER_X; curve: EC_CURVE_FP): EC_POINT_FP + do + Result := Precursor (other, curve) + end + + product (other: INTEGER_X; curve: EC_CURVE_FP) + -- return current * k over FP + local + e: INTEGER_X + h: INTEGER_X + R: like Current + i: INTEGER_32 + do + if + infinity + then + elseif + other.is_zero + then + set_infinity + else + e := other + h := e * three + R := deep_twin + from + i := (h.bits - 2) + until + i <= 0 + loop + R := r.twice_value (curve) + if + h.bit_test (i) and not e.bit_test (i) + then + r := r.plus_value (Current, curve) + elseif + not h.bit_test (i) and e.bit_test (i) + then + r := r.minus_value (Current, curve) + end + i := i - 1 + end + copy (r) + end + end + + opposite_value (curve: EC_CURVE_FP): like Current + do + Result := Precursor (curve) + end + + opposite (curve: EC_CURVE_FP) + do + y.opposite (curve) + end + +feature {NONE} -- support features + ytilde_set (source: INTEGER_X): BOOLEAN + -- Test the least significant bit, this is ytilde + -- X9.62 4.2.1 + do + result := source.bit_test (0) + end + + compressed_PC_byte (source: INTEGER_X): NATURAL_8 + -- Return the PC byte depending on if ytilde is set + -- X9.62 4.3.6 + do + if + ytilde_set (source) + then + result := 0x03 + else + result := 0x02 + end + end + +feature {NONE} + decodeCompressedPoint (encoded: SPECIAL [NATURAL_8] ytilde: INTEGER curve: EC_CURVE_FP) + -- Decode a compressed point + require + encoded.lower = 0 + local + i: SPECIAL [NATURAL_8] + x_new: EC_FIELD_ELEMENT_FP + alpha: EC_FIELD_ELEMENT_FP + beta: EC_FIELD_ELEMENT_FP + x_int: INTEGER_X + bit0: INTEGER + q_minus_beta: EC_FIELD_ELEMENT_FP + do + create i.make_filled (0, encoded.count - 1) + i.copy_data (encoded, 1, 0, i.count) + create x_int.make_from_bytes (i, i.lower, i.upper) + create x_new.make_p_x (x_int) + alpha := (x_new.product_value (x_new.square_value (curve).plus_value (curve.a, curve), curve)).plus_value (curve.b, curve) + beta := alpha.sqrt (curve) + if + beta.x.bit_test (0) + then + bit0 := 1 + else + bit0 := 0 + end + if + bit0 = ytilde + then + make_curve_x_y (x_new, beta) + else + create q_minus_beta.make_p_x (curve.q - beta.x) + make_curve_x_y (x_new, q_minus_beta) + end + end + + decodeUncompressedPoint (encoded: SPECIAL [NATURAL_8]) + -- Decode an uncompressed point + require + encoded_not_split_even: (encoded.count \\ 2) = 1 + local + xEnc: SPECIAL [NATURAL_8] + yEnc: SPECIAL [NATURAL_8] + x_new: EC_FIELD_ELEMENT_FP + y_new: EC_FIELD_ELEMENT_FP + do + create xEnc.make_filled (0, (encoded.capacity - 1) // 2) + create yEnc.make_filled (0, (encoded.capacity - 1) // 2) + encoded.copy_data (xEnc, 1, 0, xEnc.capacity) + encoded.copy_data (yEnc, xEnc.capacity, 0, yEnc.capacity) + create x_new.make_p_x (create {INTEGER_X}.make_from_bytes (xEnc, xEnc.lower, xEnc.upper)) + create y_new.make_p_x (create {INTEGER_X}.make_from_bytes (yEnc, yEnc.lower, yEnc.upper)) + x := x_new + y := y_new + end +end diff --git a/library/crypto/eel/ec/ec_private_key.e b/library/crypto/eel/ec/ec_private_key.e new file mode 100644 index 00000000..55f11b27 --- /dev/null +++ b/library/crypto/eel/ec/ec_private_key.e @@ -0,0 +1,89 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Liberty is always dangerous, but it is the safest thing we have. - Harry Emerson Fosdick" + +class + EC_PRIVATE_KEY + +inherit + EC_KEY_PARAMETERS + DEBUG_OUTPUT + EC_CONSTANTS + +create + make_d_params + +feature + make_d_params (d_new: INTEGER_X params_new: EC_DOMAIN_PARAMETERS) + do + params := params_new + d := d_new + end + + agreement (other: EC_PUBLIC_KEY): INTEGER_X + do + result := (other.q.product_value (d, params.curve)).x.x + ensure + symmetric: result ~ other.agreement (current) + end + + sign (e: INTEGER_X): TUPLE [r: INTEGER_X s: INTEGER_X] + require + message_too_big: e < params.n + local + r: INTEGER_X + s: INTEGER_X + k: INTEGER_X + nBitLength: INTEGER_32 + p: EC_POINT + x: INTEGER_X + n: INTEGER_X + do + n := params.n + create s.default_create + create r.default_create + create k.default_create + nBitLength := params.n.bits + from + until + s /~ s.zero + loop + from + until + r /~ r.zero + loop + from + until + k /~ k.zero + loop + create k.make_random (nBitLength) + end + p := params.g.product_value (k, params.curve) + x := p.x.x + r := x \\ params.n + end + --s := ((k.inverse_value (params.n) * (e + d * r))) \\ params.n + s := d.identity + s.product (r) + s.plus (e) + k.inverse (n) + s.product (k) + s.modulo (n) + end + create result + result.r := r + result.s := s + end + +feature + d: INTEGER_X + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := "0x" + d.out_hex + end +end diff --git a/library/crypto/eel/ec/ec_public_key.e b/library/crypto/eel/ec/ec_public_key.e new file mode 100644 index 00000000..a605a8a7 --- /dev/null +++ b/library/crypto/eel/ec/ec_public_key.e @@ -0,0 +1,74 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "It is much more important to kill bad bills than to pass good ones. - Calvin Coolidge" + +class + EC_PUBLIC_KEY + +inherit + EC_KEY_PARAMETERS + DEBUG_OUTPUT + EC_CONSTANTS + +create + make_q_parameters + +feature -- Creation procedures + make_q_parameters (q_new: EC_POINT params_new: EC_DOMAIN_PARAMETERS) + do + params := params_new + q := q_new + end + + agreement (other: EC_PRIVATE_KEY): INTEGER_X + do + Result := (q.product_value (other.d, params.curve)).x.x + ensure + symmetric: Result ~ other.agreement (Current) + end + + verify (message: INTEGER_X signature: TUPLE [r: INTEGER_X s: INTEGER_X]): BOOLEAN + do + result := verify_r_s (message, signature.r, signature.s, params.curve) + end + + verify_r_s (e: INTEGER_X r: INTEGER_X s: INTEGER_X curve: EC_CURVE): BOOLEAN + require + message_small_enough: e < params.n + local + c: INTEGER_X + u1: INTEGER_X + u2: INTEGER_X + point: EC_POINT + v: INTEGER_X + do + if + (r < r.one) or (r >= params.n) + then + result := false + elseif + (s < s.one) or (s >= params.n) + then + result := false + else + c := s.inverse_value (params.n) + u1 := e * c \\ params.n + u2 := r * c \\ params.n + point := (params.g.product_value (u1, params.curve)).plus_value (q.product_value (u2, params.curve), params.curve) + v := point.x.x \\ params.n + result := v ~ r + end + end + +feature + q: EC_POINT + +feature {DEBUG_OUTPUT} -- {DEBUG_OUTPUT} + debug_output: STRING + do + result := q.debug_output + end +end diff --git a/library/crypto/eel/ec/f2m_representations.e b/library/crypto/eel/ec/f2m_representations.e new file mode 100644 index 00000000..30f74dea --- /dev/null +++ b/library/crypto/eel/ec/f2m_representations.e @@ -0,0 +1,18 @@ +note + description: "Summary description for {F2M_REPRESENTATIONS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "To compel a man to furnish contributions of money for the propagation of opinions which he disbelieves and abhors, is sinful and tyrannical. - Thomas Jefferson" + +deferred class + F2M_REPRESENTATIONS + +feature -- Field element representations + GNB: INTEGER = 1 + + TPB: INTEGER = 2 + + PPB: INTEGER = 3 + +end diff --git a/library/crypto/eel/ec/standard_curves.e b/library/crypto/eel/ec/standard_curves.e new file mode 100644 index 00000000..e7007164 --- /dev/null +++ b/library/crypto/eel/ec/standard_curves.e @@ -0,0 +1,1807 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "It is dangerous to be right when the government is wrong. - Voltaire" + +deferred class + STANDARD_CURVES + +inherit + EC_CONSTANTS + +feature -- SEC p112r1 + sec_p112r1_p: INTEGER_X + do + create Result.make_from_hex_string ("0000DB7C 2ABF62E3 5E668076 BEAD208B") + end + + sec_p112r1_r: INTEGER_X + do + create Result.make_from_hex_string ("0000DB7C 2ABF62E3 5E7628DF AC6561C5") + end + + sec_p112r1_a: INTEGER_X + do + create Result.make_from_hex_string ("0000DB7C 2ABF62E3 5E668076 BEAD2088") + end + + sec_p112r1_b: INTEGER_X + do + create Result.make_from_hex_string ("0000659E F8BA0439 16EEDE89 11702B22") + end + + sec_p112r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("00000948 7239995A 5EE76B55 F9C2F098") + end + + sec_p112r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("0000A89C E5AF8724 C0A23E0E 0FF77500") + end + + sec_p112r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p112r2 + sec_p112r2_p: INTEGER_X + do + create Result.make_from_hex_string ("0000DB7C 2ABF62E3 5E668076 BEAD208B") + end + + sec_p112r2_r: INTEGER_X + do + create Result.make_from_hex_string ("000036DF 0AAFD8B8 D7597CA1 0520D04B") + end + + sec_p112r2_a: INTEGER_X + do + create Result.make_from_hex_string ("00006127 C24C05F3 8A0AAAF6 5C0EF02C") + end + + sec_p112r2_b: INTEGER_X + do + create Result.make_from_hex_string ("000051DE F1815DB5 ED74FCC3 4C85D709") + end + + sec_p112r2_gx: INTEGER_X + do + create Result.make_from_hex_string ("00004BA3 0AB5E892 B4E1649D D0928643") + end + + sec_p112r2_gy: INTEGER_X + do + create Result.make_from_hex_string ("0000ADCD 46F5882E 3747DEF3 6E956E97") + end + + sec_p112r2_h: INTEGER_X + do + result := four + end + +feature -- SEC p128r1 + sec_p128r1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF") + end + + sec_p128r1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFE 00000000 75A30D1B 9038A115") + end + + sec_p128r1_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFC") + end + + sec_p128r1_b: INTEGER_X + do + create Result.make_from_hex_string ("E87579C1 1079F43D D824993C 2CEE5ED3") + end + + sec_p128r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("161FF752 8B899B2D 0C28607C A52C5B86") + end + + sec_p128r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("CF5AC839 5BAFEB13 C02DA292 DDED7A83") + end + + sec_p128r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p128r2 + sec_p128r2_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF") + end + + sec_p128r2_r: INTEGER_X + do + create Result.make_from_hex_string ("3FFFFFFF 7FFFFFFF BE002472 0613B5A3") + end + + sec_p128r2_a: INTEGER_X + do + create Result.make_from_hex_string ("D6031998 D1B3BBFE BF59CC9B BFF9AEE1") + end + + sec_p128r2_b: INTEGER_X + do + create Result.make_from_hex_string ("5EEEFCA3 80D02919 DC2C6558 BB6D8A5D") + end + + sec_p128r2_gx: INTEGER_X + do + create Result.make_from_hex_string ("7B6AA5D8 5E572983 E6FB32A7 CDEBC140") + end + + sec_p128r2_gy: INTEGER_X + do + create Result.make_from_hex_string ("27B6916A 894D3AEE 7106FE80 5FC34B44") + end + + sec_p128r2_h: INTEGER_X + do + result := four + end + +feature -- SEC p160k1 + sec_p160k1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFAC73") + end + + sec_p160k1_r: INTEGER_X + do + create Result.make_from_hex_string ("01 00000000 00000000 0001B8FA 16DFAB9A CA16B6B3") + end + + sec_p160k1_a: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000") + end + + sec_p160k1_b: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000007") + end + + sec_p160k1_gx: INTEGER_X + do + create Result.make_from_hex_string ("3B4C382C E37AA192 A4019E76 3036F4F5 DD4D7EBB") + end + + sec_p160k1_gy: INTEGER_X + do + create Result.make_from_hex_string ("938CF935 318FDCED 6BC28286 531733C3 F03C4FEE") + end + + sec_p160k1_h: INTEGER_X + do + result := one + end + +feature -- SEC p160r1 + sec_p160r1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 7FFFFFFF") + end + + sec_p160r1_r: INTEGER_X + do + create Result.make_from_hex_string ("01 00000000 00000000 0001F4C8 F927AED3 CA752257") + end + + sec_p160r1_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 7FFFFFFC") + end + + sec_p160r1_b: INTEGER_X + do + create Result.make_from_hex_string ("1C97BEFC 54BD7A8B 65ACF89F 81D4D4AD C565FA45") + end + + sec_p160r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("4A96B568 8EF57328 46646989 68C38BB9 13CBFC82") + end + + sec_p160r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("23A62855 3168947D 59DCC912 04235137 7AC5FB32") + end + + sec_p160r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p160r2 + sec_p160r2_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFAC73") + end + + sec_p160r2_r: INTEGER_X + do + create Result.make_from_hex_string ("01 00000000 00000000 0000351E E786A818 F3A1A16B") + end + + sec_p160r2_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFAC70") + end + + sec_p160r2_b: INTEGER_X + do + create Result.make_from_hex_string ("B4E134D3 FB59EB8B AB572749 04664D5A F50388BA") + end + + sec_p160r2_gx: INTEGER_X + do + create Result.make_from_hex_string ("52DCB034 293A117E 1F4FF11B 30F7199D 3144CE6D") + end + + sec_p160r2_gy: INTEGER_X + do + create Result.make_from_hex_string ("FEAFFEF2 E331F296 E071FA0D F9982CFE A7D43F2E") + end + + sec_p160r2_h: INTEGER_X + do + result := one + end + +feature -- SEC p192k1 + sec_p192k1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFEE37") + end + + sec_p192k1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFE 26F2FC17 0F69466A 74DEFD8D") + end + + sec_p192k1_a: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_p192k1_b: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000003") + end + + sec_p192k1_gx: INTEGER_X + do + create Result.make_from_hex_string ("DB4FF10E C057E9AE 26B07D02 80B7F434 1DA5D1B1 EAE06C7D") + end + + sec_p192k1_gy: INTEGER_X + do + create Result.make_from_hex_string ("9B2F2F6D 9C5628A7 844163D0 15BE8634 4082AA88 D95E2F9D") + end + + sec_p192k1_h: INTEGER_X + do + result := one + end + +feature -- SEC p192r1 + sec_p192r1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF") + end + + sec_p192r1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF 99DEF836 146BC9B1 B4D22831") + end + + sec_p192r1_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFC") + end + + sec_p192r1_b: INTEGER_X + do + create Result.make_from_hex_string ("64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1") + end + + sec_p192r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012") + end + + sec_p192r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811") + end + + sec_p192r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p224k1 + sec_p224k1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D") + end + + sec_p224k1_r: INTEGER_X + do + create Result.make_from_hex_string ("01 00000000 00000000 00000000 0001DCE8 D2EC6184 CAF0A971 769FB1F7") + end + + sec_p224k1_a: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_p224k1_b: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000005") + end + + sec_p224k1_gx: INTEGER_X + do + create Result.make_from_hex_string ("A1455B33 4DF099DF 30FC28A1 69A467E9 E47075A9 0F7E650E B6B7A45C") + end + + sec_p224k1_gy: INTEGER_X + do + create Result.make_from_hex_string ("7E089FED 7FBA3442 82CAFBD6 F7E319F7 C0B0BD59 E2CA4BDB 556D61A5") + end + + sec_p224k1_h: INTEGER_X + do + result := one + end + +feature -- SEC p224r1 + sec_p224r1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 00000000 00000001") + end + + sec_p224r1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFF16A2 E0B8F03E 13DD2945 5C5C2A3D") + end + + sec_p224r1_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFE") + end + + sec_p224r1_b: INTEGER_X + do + create Result.make_from_hex_string ("B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943 2355FFB4") + end + + sec_p224r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6 115C1D21") + end + + sec_p224r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199 85007E34") + end + + sec_p224r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p256k1 + sec_p256k1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F") + end + + sec_p256k1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141") + end + + sec_p256k1_a: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_p256k1_b: INTEGER_X + do + create Result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007") + end + + sec_p256k1_gx: INTEGER_X + do + create Result.make_from_hex_string ("79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798") + end + + sec_p256k1_gy: INTEGER_X + do + create Result.make_from_hex_string ("483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8") + end + + sec_p256k1_h: INTEGER_X + do + result := one + end + +feature -- SEC p256r1 + sec_p256r1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF") + end + + sec_p256r1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551") + end + + sec_p256r1_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC") + end + + sec_p256r1_b: INTEGER_X + do + create Result.make_from_hex_string ("5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B") + end + + sec_p256r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296") + end + + sec_p256r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5") + end + + sec_p256r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p384r1 + sec_p384r1_p: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFF") + end + + sec_p384r1_r: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF C7634D81 F4372DDF 581A0DB2 48B0A77A ECEC196A CCC52973") + end + + sec_p384r1_a: INTEGER_X + do + create Result.make_from_hex_string ("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFC") + end + + sec_p384r1_b: INTEGER_X + do + create Result.make_from_hex_string ("B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112 0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF") + end + + sec_p384r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98 59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7") + end + + sec_p384r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F") + end + + sec_p384r1_h: INTEGER_X + do + result := one + end + +feature -- SEC p521r1 + sec_p521r1_p: INTEGER_X + do + create Result.make_from_hex_string ("000001FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF") + end + + sec_p521r1_r: INTEGER_X + do + create Result.make_from_hex_string ("000001FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFA 51868783 BF2F966B 7FCC0148 F709A5D0 3BB5C9B8 899C47AE BB6FB71E 91386409") + end + + sec_p521r1_a: INTEGER_X + do + create Result.make_from_hex_string ("000001FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC") + end + + sec_p521r1_b: INTEGER_X + do + create Result.make_from_hex_string ("00000051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B 99B315F3 B8B48991 8EF109E1 56194951 EC7A937B 1652C0BD 3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00") + end + + sec_p521r1_gx: INTEGER_X + do + create Result.make_from_hex_string ("000000C6 858E06B7 0404E9CD 9E3ECB66 2395B442 9C648139 053FB521 F828AF60 6B4D3DBA A14B5E77 EFE75928 FE1DC127 A2FFA8DE 3348B3C1 856A429B F97E7E31 C2E5BD66") + end + + sec_p521r1_gy: INTEGER_X + do + create Result.make_from_hex_string ("00000118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449 579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901 3FAD0761 353C7086 A272C240 88BE9476 9FD16650") + end + + sec_p521r1_h: INTEGER_X + do + result := one + end + +feature -- SEC t113r1 + sec_t113r1_m: INTEGER_32 = 113 + + sec_t113r1_k1: INTEGER_32 = 9 + + sec_t113r1_k2: INTEGER_32 = 0 + + sec_t113r1_k3: INTEGER_32 = 0 + + sec_t113r1_a: INTEGER_X + do + create result.make_from_hex_string ("00003088 250CA6E7 C7FE649C E85820F7") + end + + sec_t113r1_b: INTEGER_X + do + create result.make_from_hex_string ("0000E8BE E4D3E226 0744188B E0E9C723") + end + + sec_t113r1_r: INTEGER_X + do + create result.make_from_hex_string ("00010000 00000000 00D9CCEC 8A39E56F") + end + + sec_t113r1_h: INTEGER_X + do + result := two + end + + sec_t113r1_gx: INTEGER_X + do + create result.make_from_hex_string ("00009D73 616F35F4 AB1407D7 3562C10F") + end + + sec_t113r1_gy: INTEGER_X + do + create result.make_from_hex_string ("0000A528 30277958 EE84D131 5ED31886") + end + +feature -- SEC t113r2 + sec_t113r2_m: INTEGER_32 = 113 + + sec_t113r2_k1: INTEGER_32 = 9 + + sec_t113r2_k2: INTEGER_32 = 0 + + sec_t113r2_k3: INTEGER_32 = 0 + + sec_t113r2_a: INTEGER_X + do + create result.make_from_hex_string ("00006899 18DBEC7E 5A0DD6DF C0AA55C7") + end + + sec_t113r2_b: INTEGER_X + do + create result.make_from_hex_string ("000095E9 A9EC9B29 7BD4BF36 E059184F") + end + + sec_t113r2_r: INTEGER_X + do + create result.make_from_hex_string ("00010000 00000000 0108789B 2496AF93") + end + + sec_t113r2_h: INTEGER_X + do + result := two + end + + sec_t113r2_gx: INTEGER_X + do + create result.make_from_hex_string ("0001A57A 6A7B26CA 5EF52FCD B8164797") + end + + sec_t113r2_gy: INTEGER_X + do + create result.make_from_hex_string ("0000B3AD C94ED1FE 674C06E6 95BABA1D") + end + +feature -- SEC t131r1 + sec_t131r1_m: INTEGER_32 = 131 + + sec_t131r1_k1: INTEGER_32 = 2 + + sec_t131r1_k2: INTEGER_32 = 3 + + sec_t131r1_k3: INTEGER_32 = 8 + + sec_t131r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000007 A11B09A7 6B562144 418FF3FF 8C2570B8") + end + + sec_t131r1_b: INTEGER_X + do + create result.make_from_hex_string ("00000002 17C05610 884B63B9 C6C72916 78F9D341") + end + + sec_t131r1_r: INTEGER_X + do + create result.make_from_hex_string ("00000004 00000000 00000002 3123953A 9464B54D") + end + + sec_t131r1_h: INTEGER_X + do + result := two + end + + sec_t131r1_gx: INTEGER_X + do + create result.make_from_hex_string ("00000000 81BAF91F DF9833C4 0F9C1813 43638399") + end + + sec_t131r1_gy: INTEGER_X + do + create result.make_from_hex_string ("00000007 8C6E7EA3 8C001F73 C8134B1B 4EF9E150") + end + +feature -- SEC t131r2 + sec_t131r2_m: INTEGER_32 = 131 + + sec_t131r2_k1: INTEGER_32 = 2 + + sec_t131r2_k2: INTEGER_32 = 3 + + sec_t131r2_k3: INTEGER_32 = 8 + + sec_t131r2_a: INTEGER_X + do + create result.make_from_hex_string ("00000003 E5A88919 D7CAFCBF 415F07C2 176573B2") + end + + sec_t131r2_b: INTEGER_X + do + create result.make_from_hex_string ("00000004 B8266A46 C55657AC 734CE38F 018F2192") + end + + sec_t131r2_r: INTEGER_X + do + create result.make_from_hex_string ("00000004 00000000 00000001 6954A233 049BA98F") + end + + sec_t131r2_h: INTEGER_X + do + result := two + end + + sec_t131r2_gx: INTEGER_X + do + create result.make_from_hex_string ("00000003 56DCD8F2 F95031AD 652D2395 1BB366A8") + end + + sec_t131r2_gy: INTEGER_X + do + create result.make_from_hex_string ("00000006 48F06D86 7940A536 6D9E265D E9EB240F") + end + +feature --SEC t163k1 + sec_t163k1_m: INTEGER_32 = 163 + + sec_t163k1_k1: INTEGER_32 = 3 + + sec_t163k1_k2: INTEGER_32 = 6 + + sec_t163k1_k3: INTEGER_32 = 7 + + sec_t163k1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t163k1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t163k1_r: INTEGER_X + do + create result.make_from_hex_string ("00000004 00000000 00000000 00020108 A2E0CC0D 99F8A5EF") + end + + sec_t163k1_h: INTEGER_X + do + result := two + end + + sec_t163k1_gx: INTEGER_X + do + create result.make_from_hex_string ("00000002 FE13C053 7BBC11AC AA07D793 DE4E6D5E 5C94EEE8") + end + + sec_t163k1_gy: INTEGER_X + do + create result.make_from_hex_string ("00000002 89070FB0 5D38FF58 321F2E80 0536D538 CCDAA3D9") + end + +feature --SEC t163r1 + sec_t163r1_m: INTEGER_32 = 163 + + sec_t163r1_k1: INTEGER_32 = 3 + + sec_t163r1_k2: INTEGER_32 = 6 + + sec_t163r1_k3: INTEGER_32 = 7 + + sec_t163r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000007 B6882CAA EFA84F95 54FF8428 BD88E246 D2782AE2") + end + + sec_t163r1_b: INTEGER_X + do + create result.make_from_hex_string ("00000007 13612DCD DCB40AAB 946BDA29 CA91F73A F958AFD9") + end + + sec_t163r1_r: INTEGER_X + do + create result.make_from_hex_string ("00000003 FFFFFFFF FFFFFFFF FFFF48AA B689C29C A710279B") + end + + sec_t163r1_h: INTEGER_X + do + result := two + end + + sec_t163r1_gx: INTEGER_X + do + create result.make_from_hex_string ("00000003 69979697 AB438977 89566789 567F787A 7876A654") + end + + sec_t163r1_gy: INTEGER_X + do + create result.make_from_hex_string ("00000000 435EDB42 EFAFB298 9D51FEFC E3C80988 F41FF883") + end + +feature --SEC t163r2 + sec_t163r2_m: INTEGER_32 = 163 + + sec_t163r2_k1: INTEGER_32 = 3 + + sec_t163r2_k2: INTEGER_32 = 6 + + sec_t163r2_k3: INTEGER_32 = 7 + + sec_t163r2_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t163r2_b: INTEGER_X + do + create result.make_from_hex_string ("00000002 0A601907 B8C953CA 1481EB10 512F7874 4A3205FD") + end + + sec_t163r2_r: INTEGER_X + do + create result.make_from_hex_string ("00000004 00000000 00000000 000292FE 77E70C12 A4234C33") + end + + sec_t163r2_h: INTEGER_X + do + result := two + end + + sec_t163r2_gx: INTEGER_X + do + create result.make_from_hex_string ("00000003 F0EBA162 86A2D57E A0991168 D4994637 E8343E36") + end + + sec_t163r2_gy: INTEGER_X + do + create result.make_from_hex_string ("00000000 D51FBC6C 71A0094F A2CDD545 B11C5C0C 797324F1") + end + +feature --SEC t193r1 + sec_t193r1_m: INTEGER_32 = 193 + + sec_t193r1_k1: INTEGER_32 = 15 + + sec_t193r1_k2: INTEGER_32 = 0 + + sec_t193r1_k3: INTEGER_32 = 0 + + sec_t193r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 17858FEB 7A989751 69E171F7 7B4087DE 098AC8A9 11DF7B01") + end + + sec_t193r1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 FDFB49BF E6C3A89F ACADAA7A 1E5BBC7C C1C2E5D8 31478814") + end + + sec_t193r1_r: INTEGER_X + do + create result.make_from_hex_string ("00000001 00000000 00000000 00000000 C7F34A77 8F443ACC 920EBA49") + end + + sec_t193r1_h: INTEGER_X + do + result := two + end + + sec_t193r1_gx: INTEGER_X + do + create result.make_from_hex_string ("00000001 F481BC5F 0FF84A74 AD6CDF6F DEF4BF61 79625372 D8C0C5E1") + end + + sec_t193r1_gy: INTEGER_X + do + create result.make_from_hex_string ("00000000 25E399F2 903712CC F3EA9E3A 1AD17FB0 B3201B6A F7CE1B05") + end + +feature --SEC t193r2 + sec_t193r2_m: INTEGER_32 = 193 + + sec_t193r2_k1: INTEGER_32 = 15 + + sec_t193r2_k2: INTEGER_32 = 0 + + sec_t193r2_k3: INTEGER_32 = 0 + + sec_t193r2_a: INTEGER_X + do + create result.make_from_hex_string ("00000001 63F35A51 37C2CE3E A6ED8667 190B0BC4 3ECD6997 7702709B") + end + + sec_t193r2_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 C9BB9E89 27D4D64C 377E2AB2 856A5B16 E3EFB7F6 1D4316AE") + end + + sec_t193r2_r: INTEGER_X + do + create result.make_from_hex_string ("00000001 00000000 00000000 00000001 5AAB561B 005413CC D4EE99D5") + end + + sec_t193r2_h: INTEGER_X + do + result := two + end + + sec_t193r2_gx: INTEGER_X + do + create result.make_from_hex_string ("00000000 D9B67D19 2E0367C8 03F39E1A 7E82CA14 A651350A AE617E8F") + end + + sec_t193r2_gy: INTEGER_X + do + create result.make_from_hex_string ("00000001 CE943356 07C304AC 29E7DEFB D9CA01F5 96F92722 4CDECF6C") + end + +feature --SEC t233k1 + sec_t233k1_m: INTEGER_32 = 233 + + sec_t233k1_k1: INTEGER_32 = 74 + + sec_t233k1_k2: INTEGER_32 = 0 + + sec_t233k1_k3: INTEGER_32 = 0 + + sec_t233k1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_t233k1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t233k1_r: INTEGER_X + do + create result.make_from_hex_string ("00000080 00000000 00000000 00000000 00069D5B B915BCD4 6EFB1AD5 F173ABDF") + end + + sec_t233k1_h: INTEGER_X + do + result := two + end + + sec_t233k1_gx: INTEGER_X + do + create result.make_from_hex_string ("00000172 32BA853A 7E731AF1 29F22FF4 149563A4 19C26BF5 0A4C9D6E EFAD6126") + end + + sec_t233k1_gy: INTEGER_X + do + create result.make_from_hex_string ("0000001D B537DECE 819B7F70 F555A67C 427A8CD9 BF18AEB9 B56E0C11 056FAE6A3") + end + +feature --SEC t233r1 + sec_t233r1_m: INTEGER_32 = 233 + + sec_t233r1_k1: INTEGER_32 = 74 + + sec_t233r1_k2: INTEGER_32 = 0 + + sec_t233r1_k3: INTEGER_32 = 0 + + sec_t233r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t233r1_b: INTEGER_X + do + create result.make_from_hex_string ("00000066 647EDE6C 332C7F8C 0923BB58 213B333B 20E9CE42 81FE115F 7D8F90AD") + end + + sec_t233r1_r: INTEGER_X + do + create result.make_from_hex_string ("00000100 00000000 00000000 00000000 0013E974 E72F8A69 22031D26 03CFE0D7") + end + + sec_t233r1_h: INTEGER_X + do + result := two + end + + sec_t233r1_gx: INTEGER_X + do + create result.make_from_hex_string ("000000FA C9DFCBAC 8313BB21 39F1BB75 5FEF65BC 391F8B36 F8F8EB73 71FD558B") + end + + sec_t233r1_gy: INTEGER_X + do + create result.make_from_hex_string ("00000100 6A08A419 03350678 E58528BE BF8A0BEF F867A7CA 36716F7E 01F81052") + end + +feature --SEC t239k1 + sec_t239k1_m: INTEGER_32 = 239 + + sec_t239k1_k1: INTEGER_32 = 158 + + sec_t239k1_k2: INTEGER_32 = 0 + + sec_t239k1_k3: INTEGER_32 = 0 + + sec_t239k1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_t239k1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t239k1_r: INTEGER_X + do + create result.make_from_hex_string ("00002000 00000000 00000000 00000000 005A79FE C67CB6E9 1F1C1DA8 00E478A5") + end + + sec_t239k1_h: INTEGER_X + do + result := two + end + + sec_t239k1_gx: INTEGER_X + do + create result.make_from_hex_string ("000029A0 B6A887A9 83E97309 88A68727 A8B2D126 C44CC2CC 7B2A6555 193035DC") + end + + sec_t239k1_gy: INTEGER_X + do + create result.make_from_hex_string ("00007631 0804F12E 549BDB01 1C103089 E73510AC B275FC31 2A5DC6B7 6553F0CA") + end + +feature --SEC t283k1 + sec_t283k1_m: INTEGER_32 = 283 + + sec_t283k1_k1: INTEGER_32 = 5 + + sec_t283k1_k2: INTEGER_32 = 7 + + sec_t283k1_k3: INTEGER_32 = 12 + + sec_t283k1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_t283k1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t283k1_r: INTEGER_X + do + create result.make_from_hex_string ("01FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFE9AE 2ED07577 265DFF7F 94451E06 1E163C61") + end + + sec_t283k1_h: INTEGER_X + do + result := two + end + + sec_t283k1_gx: INTEGER_X + do + create result.make_from_hex_string ("0503213F 78CA4488 3F1A3B81 62F188E5 53CD265F 23C1567A 16876913 B0C2AC24 58492836") + end + + sec_t283k1_gy: INTEGER_X + do + create result.make_from_hex_string ("01CCDA38 0F1C9E31 8D90F95D 07E5426F E87E45C0 E8184698 E4596236 4E341161 77DD2259") + end + +feature --SEC t283r1 + sec_t283r1_m: INTEGER_32 = 283 + + sec_t283r1_k1: INTEGER_32 = 5 + + sec_t283r1_k2: INTEGER_32 = 7 + + sec_t283r1_k3: INTEGER_32 = 12 + + sec_t283r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t283r1_b: INTEGER_X + do + create result.make_from_hex_string ("027B680A C8B8596D A5A4AF8A 19A0303F CA97FD76 45309FA2 A581485A F6263E31 3B79A2F5") + end + + sec_t283r1_r: INTEGER_X + do + create result.make_from_hex_string ("03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFEF90 399660FC 938A9016 5B042A7C EFADB307") + end + + sec_t283r1_h: INTEGER_X + do + result := two + end + + sec_t283r1_gx: INTEGER_X + do + create result.make_from_hex_string ("05F93925 8DB7DD90 E1934F8C 70B0DFEC 2EED25B8 557EAC9C 80E2E198 F8CDBECD 86B12053") + end + + sec_t283r1_gy: INTEGER_X + do + create result.make_from_hex_string ("03676854 FE24141C B98FE6D4 B20D02B4 516FF702 350EDDB0 826779C8 13F0DF45 BE8112F4") + end + +feature --SEC t409k1 + sec_t409k1_m: INTEGER_32 = 409 + + sec_t409k1_k1: INTEGER_32 = 87 + + sec_t409k1_k2: INTEGER_32 = 0 + + sec_t409k1_k3: INTEGER_32 = 0 + + sec_t409k1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_t409k1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t409k1_r: INTEGER_X + do + create result.make_from_hex_string ("007FFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFE5F 83B2D4EA 20400EC4 557D5ED3 E3E7CA5B 4B5C83B8 E01E5FCF") + end + + sec_t409k1_h: INTEGER_X + do + result := two + end + + sec_t409k1_gx: INTEGER_X + do + create result.make_from_hex_string ("0060F05F 658F49C1 AD3AB189 0F718421 0EFD0987 E307C84C 27ACCFB8 F9F67CC2 C460189E B5AAAA62 EE222EB1 B35540CF E9023746") + end + + sec_t409k1_gy: INTEGER_X + do + create result.make_from_hex_string ("01E36905 0B7C4E42 ACBA1DAC BF04299C 3460782F 918EA427 E6325165 E9EA10E3 DA5F6C42 E9C55215 AA9CA27A 5863EC48 D8E0286B") + end + +feature --SEC t409r1 + sec_t409r1_m: INTEGER_32 = 409 + + sec_t409r1_k1: INTEGER_32 = 87 + + sec_t409r1_k2: INTEGER_32 = 0 + + sec_t409r1_k3: INTEGER_32 = 0 + + sec_t409r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t409r1_b: INTEGER_X + do + create result.make_from_hex_string ("0021A5C2 C8EE9FEB 5C4B9A75 3B7B476B 7FD6422E F1F3DD67 4761FA99 D6AC27C8 A9A197B2 72822F6C D57A55AA 4F50AE31 7B13545F") + end + + sec_t409r1_r: INTEGER_X + do + create result.make_from_hex_string ("01000000 00000000 00000000 00000000 00000000 00000000 000001E2 AAD6A612 F33307BE 5FA47C3C 9E052F83 8164CD37 D9A21173") + end + + sec_t409r1_h: INTEGER_X + do + result := two + end + + sec_t409r1_gx: INTEGER_X + do + create result.make_from_hex_string ("015D4860 D088DDB3 496B0C60 64756260 441CDE4A F1771D4D B01FFE5B 34E59703 DC255A86 8A118051 5603AEAB 60794E54 BB7996A7") + end + + sec_t409r1_gy: INTEGER_X + do + create result.make_from_hex_string ("0061B1CF AB6BE5F3 2BBFA783 24ED106A 7636B9C5 A7BD198D 0158AA4F 5488D08F 38514F1F DF4B4F40 D2181B36 81C364BA 0273C706") + end + +feature --SEC t571k1 + sec_t571k1_m: INTEGER_32 = 571 + + sec_t571k1_k1: INTEGER_32 = 2 + + sec_t571k1_k2: INTEGER_32 = 5 + + sec_t571k1_k3: INTEGER_32 = 10 + + sec_t571k1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000") + end + + sec_t571k1_b: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t571k1_r: INTEGER_X + do + create result.make_from_hex_string ("02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850E1 F19A63E4 B391A8DB 917F4138 B630D84B E5D63938 1E91DEB4 5CFE778F 637C1001") + end + + sec_t571k1_h: INTEGER_X + do + result := two + end + + sec_t571k1_gx: INTEGER_X + do + create result.make_from_hex_string ("026EB7A8 59923FBC 82189631 F8103FE4 AC9CA297 0012D5D4 60248048 01841CA4 43709584 93B205E6 47DA304D B4CEB08C BBD1BA39 494776FB 988B4717 4DCA88C7 E2945283 A01C8972") + end + + sec_t571k1_gy: INTEGER_X + do + create result.make_from_hex_string ("0349DC80 7F4FBF37 4F4AEADE 3BCA9531 4DD58CEC 9F307A54 FFC61EFC 006D8A2C 9D4979C0 AC44AEA7 4FBEBBB9 F772AEDC B620B01A 7BA7AF1B 320430C8 591984F6 01CD4C14 3EF1C7A3") + end + +feature --SEC t571r1 + sec_t571r1_m: INTEGER_32 = 571 + + sec_t571r1_k1: INTEGER_32 = 2 + + sec_t571r1_k2: INTEGER_32 = 5 + + sec_t571r1_k3: INTEGER_32 = 10 + + sec_t571r1_a: INTEGER_X + do + create result.make_from_hex_string ("00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001") + end + + sec_t571r1_b: INTEGER_X + do + create result.make_from_hex_string ("02F40E7E 2221F295 DE297117 B7F3D62F 5C6A97FF CB8CEFF1 CD6BA8CE 4A9A18AD 84FFABBD 8EFA5933 2BE7AD67 56A66E29 4AFD185A 78FF12AA 520E4DE7 39BACA0C 7FFEFF7F 2955727A") + end + + sec_t571r1_r: INTEGER_X + do + create result.make_from_hex_string ("03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF E661CE18 FF559873 08059B18 6823851E C7DD9CA1 161DE93D 5174D66E 8382E9BB 2FE84E47") + end + + sec_t571r1_h: INTEGER_X + do + result := two + end + + sec_t571r1_gx: INTEGER_X + do + create result.make_from_hex_string ("0303001D 34B85629 6C16C0D4 0D3CD775 0A93D1D2 955FA80A A5F40FC8 DB7B2ABD BDE53950 F4C0D293 CDD711A3 5B67FB14 99AE6003 8614F139 4ABFA3B4 C850D927 E1E7769C 8EEC2D19") + end + + sec_t571r1_gy: INTEGER_X + do + create result.make_from_hex_string ("037BF273 42DA639B 6DCCFFFE B73D69D7 8C6C27A6 009CBBCA 1980F853 3921E8A6 84423E43 BAB08A57 6291AF8F 461BB2A8 B3531D2F 0485C19B 16E2F151 6E23DD3C 1A4827AF 1B8AC15B") + end + +--SEC uses different names than FIPS +--FIPS p is called q +--FIPS s is called seed and is the input to the SHA-1 hash algorithm +--FIPS c is the output of the SHA-1 hash algorithm +--FIPS a is lcrypto_q - lcrypto_a +--FIPS Gx is x +--FIPS Gy is y +--FIPS f, which is always 1, is h +--FIPS r is n + +feature -- FIPS P-192 + p192_p: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF") + end + + p192_r: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831") + end + + p192_a: INTEGER_X + do + create result.make_from_hex_string ("fffffffffffffffffffffffffffffffefffffffffffffffc") + end + + p192_b: INTEGER_X + do + create result.make_from_hex_string ("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1") + end + + p192_gx: INTEGER_X + do + create result.make_from_hex_string ("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012") + end + + p192_gy: INTEGER_X + do + create result.make_from_hex_string ("07192b95ffc8da78631011ed6b24cdd573f977a11e794811") + end + + p192_h: INTEGER_X + do + result := one + end + +feature -- FIPS P-224 + p224_p: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001") + end + + p224_r: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D") + end + + p224_a: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE") + end + + p224_b: INTEGER_X + do + create result.make_from_hex_string ("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4") + end + + p224_gx: INTEGER_X + do + create result.make_from_hex_string ("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21") + end + + p224_gy: INTEGER_X + do + create result.make_from_hex_string ("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34") + end + + p224_h: INTEGER_X + do + result := one + end + +feature -- FIPS P-256 + p256_p: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF") + end + + p256_r: INTEGER_X + do + create result.make_from_hex_string ("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551") + end + + p256_a: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC") + ensure + result ~ (p256_p - create {INTEGER_X}.make_from_integer (3)) + end + + p256_b: INTEGER_X + do + create result.make_from_hex_string ("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b") + end + + p256_gx: INTEGER_X + do + create result.make_from_hex_string ("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296") + end + + p256_gy: INTEGER_X + do + create result.make_from_hex_string ("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5") + end + + p256_h: INTEGER_X + do + result := one + end + +feature -- FIPS p-384 + p384_p: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF") + end + + p384_r: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973") + end + + p384_a: INTEGER_X + do + create result.make_from_hex_string ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC") + end + + p384_b: INTEGER_X + do + create result.make_from_hex_string ("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF") + end + + p384_gx: INTEGER_X + do + create result.make_from_hex_string ("AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7") + end + + p384_gy: INTEGER_X + do + create result.make_from_hex_string ("3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F") + end + + p384_h: INTEGER_X + do + result := one + end + +feature -- FIPS p-521 + p521_p: INTEGER_X + do + create result.make_from_string ("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151") + end + + p521_r: INTEGER_X + do + create result.make_from_hex_string ("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409") + end + + p521_a: INTEGER_X + do + create result.make_from_string ("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057148") + end + + p521_b: INTEGER_X + do + create result.make_from_hex_string ("051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00") + end + + p521_gx: INTEGER_X + do + create result.make_from_hex_string ("c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66") + end + + p521_gy: INTEGER_X + do + create result.make_from_hex_string ("11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650") + end + + p521_h: INTEGER_X + do + result := one + end + +feature -- FIPS K-163 + k163_m: INTEGER = 163 + k163_k1: INTEGER = 3 + k163_k2: INTEGER = 6 + k163_k3: INTEGER = 7 + + k163_a: INTEGER_X + do + result := one + end + + k163_b: INTEGER_X + do + result := one + end + + k163_r: INTEGER_X + do + create result.make_from_hex_string ("5846006549323611672814741753598448348329118574063") + end + + k163_h: INTEGER_X + do + result := two + end + + k163_gx: INTEGER_X + do + create result.make_from_hex_string ("00000002 FE13C053 7BBC11AC AA07D793 DE4E6D5E 5C94EEE8") + end + + k163_gy: INTEGER_X + do + create result.make_from_hex_string ("00000002 89070FB0 5D38FF58 321F2E80 0536D538 CCDAA3D9") + end + +feature -- FIPS K-233 + k233_m: INTEGER = 233 + k233_k1: INTEGER = 0 + k233_k2: INTEGER = 0 + k233_k3: INTEGER = 71 + + k233_a: INTEGER_X + do + result := zero + end + + k233_b: INTEGER_X + do + result := one + end + + k233_r: INTEGER_X + do + create result.make_from_hex_string ("8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF") + end + + k233_h: INTEGER_X + do + result := four + end + + k233_gx: INTEGER_X + do + create result.make_from_hex_string ("17232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126") + end + + k233_gy: INTEGER_X + do + create result.make_from_hex_string ("1db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3") + end + +feature -- FIPS K-283 + k283_m: INTEGER = 283 + k283_k1: INTEGER = 5 + k283_k2: INTEGER = 7 + k283_k3: INTEGER = 12 + + k283_a: INTEGER_X + do + result := zero + end + + k283_b: INTEGER_X + do + result := one + end + + k283_r: INTEGER_X + do + create result.make_from_hex_string ("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61") + end + + k283_h: INTEGER_X + do + result := four + end + + k283_gx: INTEGER_X + do + create result.make_from_hex_string ("503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836") + end + + k283_gy: INTEGER_X + do + create result.make_from_hex_string ("1ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259") + end + +feature -- FIPS K-409 + k409_m: INTEGER = 409 + k409_k1: INTEGER = 0 + k409_k2: INTEGER = 0 + k409_k3: INTEGER = 87 + + k409_a: INTEGER_X + do + result := zero + end + + k409_b: INTEGER_X + do + result := one + end + + k409_r: INTEGER_X + do + create result.make_from_hex_string ("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF") + end + + k409_h: INTEGER_X + do + result := four + end + + k409_gx: INTEGER_X + do + create result.make_from_hex_string ("0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746") + end + + k409_gy: INTEGER_X + do + create result.make_from_hex_string ("01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B") + end + +feature -- FIPS K-571 + k571_m: INTEGER = 571 + k571_k1: INTEGER = 2 + k571_k2: INTEGER = 5 + k571_k3: INTEGER = 10 + + k571_a: INTEGER_X + do + result := zero + end + + k571_b: INTEGER_X + do + result := one + end + + k571_r: INTEGER_X + do + create result.make_from_hex_string ("020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001") + end + + k571_h: INTEGER_X + do + result := four + end + + k571_gx: INTEGER_X + do + create result.make_from_hex_string ("026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972") + end + + k571_gy: INTEGER_X + do + create result.make_from_hex_string ("0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3") + end + +feature -- FIPS B-163 + b163_m: INTEGER = 163 + b163_k1: INTEGER = 3 + b163_k2: INTEGER = 6 + b163_k3: INTEGER = 7 + + b163_a: INTEGER_X + do + result := one + end + + b163_b: INTEGER_X + do + create result.make_from_hex_string ("020A601907B8C953CA1481EB10512F78744A3205FD") + end + + b163_r: INTEGER_X + do + create result.make_from_hex_string ("040000000000000000000292FE77E70C12A4234C33") + end + + b163_h: INTEGER_X + do + result := two + end + + b163_gx: INTEGER_X + do + create result.make_from_hex_string ("03F0EBA16286A2D57EA0991168D4994637E8343E36") + end + + b163_gy: INTEGER_X + do + create result.make_from_hex_string ("00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1") + end + +feature -- FIPS B-233 + b233_m: INTEGER = 233 + b233_k1: INTEGER = 0 + b233_k2: INTEGER = 0 + b233_k3: INTEGER = 71 + + b233_a: INTEGER_X + do + result := one + end + + b233_b: INTEGER_X + do + create result.make_from_hex_string ("0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD") + end + + b233_r: INTEGER_X + do + create result.make_from_hex_string ("01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7") + end + + b233_h: INTEGER_X + do + result := two + end + + b233_gx: INTEGER_X + do + create result.make_from_hex_string ("00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B") + end + + b233_gy: INTEGER_X + do + create result.make_from_hex_string ("01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052") + end + +feature -- FIPS B-283 + b283_m: INTEGER = 283 + b283_k1: INTEGER = 5 + b283_k2: INTEGER = 7 + b283_k3: INTEGER = 12 + + b283_a: INTEGER_X + do + result := one + end + + b283_b: INTEGER_X + do + result := one + end + + b283_r: INTEGER_X + do + create result.make_from_hex_string ("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307") + end + + b283_h: INTEGER_X + do + result := two + end + + b283_gx: INTEGER_X + do + create result.make_from_hex_string ("05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053") + end + + b283_gy: INTEGER_X + do + create result.make_from_hex_string ("03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4") + end + +feature -- FIPS B-409 + b409_m: INTEGER = 409 + b409_k1: INTEGER = 0 + b409_k2: INTEGER = 0 + b409_k3: INTEGER = 87 + + b409_a: INTEGER_X + do + result := one + end + + b409_b: INTEGER_X + do + create result.make_from_hex_string ("0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F") + end + + b409_r: INTEGER_X + do + create result.make_from_hex_string ("010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173") + end + + b409_h: INTEGER_X + do + result := two + end + + b409_gx: INTEGER_X + do + create result.make_from_hex_string ("015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7") + end + + b409_gy: INTEGER_X + do + create result.make_from_hex_string ("0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706") + end + +feature -- FIPS B-571 + b571_m: INTEGER = 571 + b571_k1: INTEGER = 2 + b571_k2: INTEGER = 5 + b571_k3: INTEGER = 10 + + b571_a: INTEGER_X + do + result := one + end + + b571_b: INTEGER_X + do + create result.make_from_hex_string ("2f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a") + end + + b571_r: INTEGER_X + do + create result.make_from_hex_string ("03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47") + end + + b571_h: INTEGER_X + do + result := two + end + + b571_gx: INTEGER_X + do + create result.make_from_hex_string ("303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19") + end + + b571_gy: INTEGER_X + do + create result.make_from_hex_string ("037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B") + end +end diff --git a/library/crypto/eel/eel-safe.ecf b/library/crypto/eel/eel-safe.ecf new file mode 100644 index 00000000..302d153d --- /dev/null +++ b/library/crypto/eel/eel-safe.ecf @@ -0,0 +1,26 @@ + + + + + /EIFGENs$ + /CVS$ + /.svn$ + /.hg$ + + + + + + + + + /x509$ + /tests$ + + + + diff --git a/library/crypto/eel/eel.ecf b/library/crypto/eel/eel.ecf new file mode 100644 index 00000000..b752a848 --- /dev/null +++ b/library/crypto/eel/eel.ecf @@ -0,0 +1,25 @@ + + + + + /\.svn$ + /\.hg$ + /CVS$ + /EIFGENs$ + + + + + + + + + /tests + + + + diff --git a/library/crypto/eel/eel.ecf.orig b/library/crypto/eel/eel.ecf.orig new file mode 100644 index 00000000..f97feef1 --- /dev/null +++ b/library/crypto/eel/eel.ecf.orig @@ -0,0 +1,23 @@ + + + + + + + + + + + /EIFGENs$ + /CVS$ + /.svn$ + /tests + /.hg$ + + + + diff --git a/library/crypto/eel/hmac/hmac_sha256.e b/library/crypto/eel/hmac/hmac_sha256.e new file mode 100644 index 00000000..bb8a177f --- /dev/null +++ b/library/crypto/eel/hmac/hmac_sha256.e @@ -0,0 +1,133 @@ +note + description: "Summary description for {HMAC_SHA256}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The bureaucracy is expanding to meet the needs of an expanding bureaucracy." + +class + HMAC_SHA256 + +inherit + BYTE_FACILITIES + +create + + make, + make_ascii_key + +feature {NONE} + + make (key_a: READABLE_INTEGER_X) + local + reduced_key: READABLE_INTEGER_X + do + if key_a.bytes <= 64 then + reduced_key := pad_key (key_a) + else + reduced_key := reduce_key (key_a) + end + ipad := (reduced_key.bit_xor_value (create {INTEGER_X}.make_from_hex_string ("36363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636"))).as_fixed_width_byte_array (64) + opad := (reduced_key.bit_xor_value (create {INTEGER_X}.make_from_hex_string ("5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c"))).as_fixed_width_byte_array (64) + create hmac.default_create + create message_hash.make + feed_inner_mix + end + + make_ascii_key (key_a: READABLE_STRING_8) + local + key_bytes: SPECIAL [NATURAL_8] + i: INTEGER + do + create key_bytes.make_filled (0, key_a.count) + from + i := 1 + until + i > key_a.count + loop + key_bytes [i - 1] := key_a [i].code.to_natural_8 + i := i + 1 + end + make (create {INTEGER_X}.make_from_bytes (key_bytes, 0, key_bytes.count - 1)) + end + +feature + + finish + local + hash_inner: SPECIAL [NATURAL_8] + hash_outer: SPECIAL [NATURAL_8] + hmac_hash: SHA256 + do + create hash_inner.make_filled (0, 32) + message_hash.do_final (hash_inner, 0) + create hmac_hash.make + hmac_hash.sink_special_lsb (opad, 0, 63) + hmac_hash.sink_special_lsb (hash_inner, 0, 31) + create hash_outer.make_filled (0, 32) + hmac_hash.do_final (hash_outer, 0) + create hmac.make_from_bytes (hash_outer, 0, 31) + finished := True + ensure + finished + end + + finished: BOOLEAN + + hmac: INTEGER_X +-- require +-- finished +-- attribute +-- end + + reset + do + message_hash.reset + finished := False + ensure + not finished + end + +feature {NONE} + + reduce_key (key_a: READABLE_INTEGER_X): INTEGER_X + require +-- key_a.bytes <= 64 + local + hash: SHA256 + result_bytes: SPECIAL [NATURAL_8] + key_bytes: SPECIAL [NATURAL_8] + do + create hash.make + key_bytes := key_a.as_bytes + hash.sink_special (key_bytes, key_bytes.lower, key_bytes.upper) + create result_bytes.make_filled (0, 64) + hash.do_final (result_bytes, 0) + create Result.make_from_bytes (result_bytes, 0, 63) + end + + pad_key (key_a: READABLE_INTEGER_X): INTEGER_X + local + key_bytes: SPECIAL [NATURAL_8] + result_bytes: SPECIAL [NATURAL_8] + do + create result_bytes.make_filled (0, 64) + key_bytes := key_a.as_bytes + result_bytes.copy_data (key_bytes, 0, 0, key_bytes.count) + create Result.make_from_bytes (result_bytes, 0, 63) + end + + feed_inner_mix + do + sink_special_lsb (ipad, 0, 63) + end + + byte_sink (in: NATURAL_8) + do + message_hash.update (in) + end + + message_hash: SHA256 + ipad: SPECIAL [NATURAL_8] + opad: SPECIAL [NATURAL_8] +end diff --git a/library/crypto/eel/modes/cbc_decryption.e b/library/crypto/eel/modes/cbc_decryption.e new file mode 100644 index 00000000..6b082532 --- /dev/null +++ b/library/crypto/eel/modes/cbc_decryption.e @@ -0,0 +1,58 @@ +note + description: "Cipher Block Chaining mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Just because you do not take an interest in politics doesn't mean politics won't take an interest in you. - Pericles (430 BC)" + +class + CBC_DECRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: CBC_TARGET iv: SPECIAL [NATURAL_8] iv_offset: INTEGER_32) + require + iv.valid_index (iv_offset) + iv.valid_index (iv_offset + target_a.block_size - 1) + do + target := target_a + create last.make_filled (0, iv.count) + last.copy_data (iv, iv_offset, 0, last.count) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cbc_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + target.decrypt_block (in, in_offset, out_array, out_offset) + array_xor (last, 0, out_array, out_offset, out_array, out_offset, block_size) + last.copy_data (in, in_offset, 0, block_size) + end + + cbc_ready: BOOLEAN + do + result := target.cbc_ready + end + +feature {NONE} + last: SPECIAL [NATURAL_8] + target: CBC_TARGET + +invariant + last.count = target.block_size +end diff --git a/library/crypto/eel/modes/cbc_encryption.e b/library/crypto/eel/modes/cbc_encryption.e new file mode 100644 index 00000000..4d0423cd --- /dev/null +++ b/library/crypto/eel/modes/cbc_encryption.e @@ -0,0 +1,57 @@ +note + description: "Cipher Block Chaining mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Nothing is so permanent as a temporary government program. - Milton Friedman" + +class + CBC_ENCRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: CBC_TARGET iv: SPECIAL [NATURAL_8] iv_offset: INTEGER_32) + require + iv.count = target_a.block_size + do + target := target_a + create last.make_filled (0, iv.count) + last.copy_data (iv, iv_offset, 0, last.count) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cbc_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + array_xor (last, 0, in, in_offset, last, 0, block_size) + target.encrypt_block (last, 0, out_array, out_offset) + last.copy_data (out_array, out_offset, 0, block_size) + end + + cbc_ready: BOOLEAN + do + result := target.cbc_ready + end + +feature {NONE} + last: SPECIAL [NATURAL_8] + target: CBC_TARGET + +invariant + last.count = target.block_size +end diff --git a/library/crypto/eel/modes/cbc_target.e b/library/crypto/eel/modes/cbc_target.e new file mode 100644 index 00000000..34f45dc8 --- /dev/null +++ b/library/crypto/eel/modes/cbc_target.e @@ -0,0 +1,41 @@ +note + description: "A block cipher that can be the target of CBC mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "I don't make jokes. I just watch the government and report the facts. - Will Rogers" + +deferred class + CBC_TARGET + +feature + block_size: INTEGER_32 + deferred + ensure + Result > 0 + end + + cbc_ready: BOOLEAN + deferred + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cbc_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cbc_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end +end diff --git a/library/crypto/eel/modes/cfb_decryption.e b/library/crypto/eel/modes/cfb_decryption.e new file mode 100644 index 00000000..e99ca241 --- /dev/null +++ b/library/crypto/eel/modes/cfb_decryption.e @@ -0,0 +1,69 @@ +note + description: "Cipher Feedback decryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The strongest reason for the people to retain the right to bear arms is, as a last resort, to protect themselves against tyranny in government. - Thomas Jefferson" + +class + CFB_DECRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: CFB_TARGET iv: SPECIAL [NATURAL_8] iv_offset: INTEGER_32 select_block_size_a: INTEGER_32) + require + iv.valid_index (iv_offset) + iv.valid_index (iv_offset + target_a.block_size - 1) + select_block_size_a > 0 + select_block_size_a <= target_a.block_size + do + select_block_size := select_block_size_a + target := target_a + create last.make_filled (0, block_size) + last.copy_data (iv, iv_offset, 0, last.count) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + select_block_size: INTEGER_32 + attribute + ensure + Result > 0 + Result <= block_size + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cfb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + select_block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + select_block_size - 1) + do + target.encrypt_block (last, 0, out_array, out_offset) + last.overlapping_move (select_block_size, 0, block_size - select_block_size) + last.copy_data (in, in_offset, block_size - select_block_size, select_block_size) + array_xor (out_array, out_offset, in, in_offset, out_array, out_offset, select_block_size) + end + + cfb_ready: BOOLEAN + do + result := target.cfb_ready + end + +feature {NONE} + last: SPECIAL [NATURAL_8] + target: CFB_TARGET + +invariant + last.count = block_size +end diff --git a/library/crypto/eel/modes/cfb_encryption.e b/library/crypto/eel/modes/cfb_encryption.e new file mode 100644 index 00000000..56e26c07 --- /dev/null +++ b/library/crypto/eel/modes/cfb_encryption.e @@ -0,0 +1,69 @@ +note + description: "Summary description for {CFB_ENCRYPTION}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The era of resisting big government is never over. - Paul Gigot (1998)" + +class + CFB_ENCRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: CFB_TARGET iv: SPECIAL [NATURAL_8] iv_offset: INTEGER_32 select_block_size_a: INTEGER_32) + require + iv.valid_index (iv_offset) + iv.valid_index (iv_offset + target_a.block_size - 1) + select_block_size_a > 0 + select_block_size_a <= target_a.block_size + do + select_block_size := select_block_size_a + target := target_a + create last.make_filled (0, block_size) + last.copy_data (iv, iv_offset, 0, last.count) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + select_block_size: INTEGER_32 + attribute + ensure + Result > 0 + Result <= block_size + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cfb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + select_block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + select_block_size - 1) + do + target.encrypt_block (last, 0, out_array, out_offset) + array_xor (out_array, out_offset, in, in_offset, out_array, out_offset, select_block_size) + last.overlapping_move (select_block_size, 0, block_size - select_block_size) + last.copy_data (out_array, out_offset, block_size - select_block_size, select_block_size) + end + + cfb_ready: BOOLEAN + do + result := target.cfb_ready + end + +feature {NONE} + last: SPECIAL [NATURAL_8] + target: CFB_TARGET + +invariant + last.count = block_size +end diff --git a/library/crypto/eel/modes/cfb_target.e b/library/crypto/eel/modes/cfb_target.e new file mode 100644 index 00000000..611ac775 --- /dev/null +++ b/library/crypto/eel/modes/cfb_target.e @@ -0,0 +1,31 @@ +note + description: "A block cipher that can be the target of CFB mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The ultimate result of shielding men from the effects of folly is to fill the world with fools. - Herbert Spencer (1891)" + +deferred class + CFB_TARGET + +feature + block_size: INTEGER_32 + deferred + ensure + Result > 0 + end + + cfb_ready: BOOLEAN + deferred + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + cfb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end +end diff --git a/library/crypto/eel/modes/ctr_decryption.e b/library/crypto/eel/modes/ctr_decryption.e new file mode 100644 index 00000000..fa27c4d8 --- /dev/null +++ b/library/crypto/eel/modes/ctr_decryption.e @@ -0,0 +1,57 @@ +note + description: "Counter decryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "If you have been voting for politicians who promise to give you goodies at someone else's expense, then you have no right to complain when they take your money and give it to someone else, including themselves. - Thomas Sowell (1992)" + +class + CTR_DECRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: CTR_TARGET iv: INTEGER_X) + do + target := target_a + create counter + counter.copy (iv) + max := counter.one.bit_shift_left_value (block_size * 8) + create counter_array.make_filled (0, block_size) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ctr_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + counter.to_fixed_width_byte_array (counter_array, 0, block_size - 1) + target.encrypt_block (counter_array, 0, out_array, out_offset) + array_xor (out_array, out_offset, in, in_offset, out_array, out_offset, block_size) + counter := (counter + counter.one) \\ max + end + + ctr_ready: BOOLEAN + do + result := target.ctr_ready + end + +feature {NONE} + counter_array: SPECIAL [NATURAL_8] + counter: INTEGER_X + max: INTEGER_X + target: CTR_TARGET +end diff --git a/library/crypto/eel/modes/ctr_encryption.e b/library/crypto/eel/modes/ctr_encryption.e new file mode 100644 index 00000000..68fee84e --- /dev/null +++ b/library/crypto/eel/modes/ctr_encryption.e @@ -0,0 +1,57 @@ +note + description: "Counter encryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "There never was a good war or a bad peace. - Benjamin Franklin (1773) " + +class + CTR_ENCRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: CTR_TARGET iv: INTEGER_X) + do + target := target_a + create counter + counter.copy (iv) + max := counter.one.bit_shift_left_value (block_size * 8) + create counter_array.make_filled (0, block_size) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ctr_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + counter.to_fixed_width_byte_array (counter_array, 0, block_size - 1) + target.encrypt_block (counter_array, 0, out_array, out_offset) + array_xor (out_array, out_offset, in, in_offset, out_array, out_offset, block_size) + counter := (counter + counter.one) \\ max + end + + ctr_ready: BOOLEAN + do + result := target.ctr_ready + end + +feature {NONE} + counter_array: SPECIAL [NATURAL_8] + counter: INTEGER_X + max: INTEGER_X + target: CTR_TARGET +end diff --git a/library/crypto/eel/modes/ctr_target.e b/library/crypto/eel/modes/ctr_target.e new file mode 100644 index 00000000..1357e549 --- /dev/null +++ b/library/crypto/eel/modes/ctr_target.e @@ -0,0 +1,31 @@ +note + description: "A block cipher that can be the target of CTR mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Everything that is really great and inspiring is created by the individual who can labor in freedom. - Albert Einstein" + +deferred class + CTR_TARGET + +feature + block_size: INTEGER_32 + deferred + ensure + Result > 0 + end + + ctr_ready: BOOLEAN + deferred + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ctr_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end +end diff --git a/library/crypto/eel/modes/ecb_decryption.e b/library/crypto/eel/modes/ecb_decryption.e new file mode 100644 index 00000000..38b63d84 --- /dev/null +++ b/library/crypto/eel/modes/ecb_decryption.e @@ -0,0 +1,44 @@ +note + description: "Electronic Codebook decryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "There are just two rules of governance in a free society: Mind your own business. Keep your hands to yourself. - P.J. O'Rourke (1993)" + +class + ECB_DECRYPTION + +create + make + +feature + make (target_a: ECB_TARGET) + do + target := target_a + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ecb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + target.decrypt_block (in, in_offset, out_array, out_offset) + end + + ecb_ready: BOOLEAN + do + result := target.ecb_ready + end + +feature {NONE} + target: ECB_TARGET +end diff --git a/library/crypto/eel/modes/ecb_encryption.e b/library/crypto/eel/modes/ecb_encryption.e new file mode 100644 index 00000000..580f257a --- /dev/null +++ b/library/crypto/eel/modes/ecb_encryption.e @@ -0,0 +1,44 @@ +note + description: "Electronic Codebook encryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Necessity is the plea for every infringement of human freedom. It is the argument of tyrants; it is the creed of slaves. - William Pitt (1783)" + +class + ECB_ENCRYPTION + +create + make + +feature + make (target_a: ECB_TARGET) + do + target := target_a + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ecb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + target.encrypt_block (in, in_offset, out_array, out_offset) + end + + ecb_ready: BOOLEAN + do + result := target.ecb_ready + end + +feature {NONE} + target: ECB_TARGET +end diff --git a/library/crypto/eel/modes/ecb_target.e b/library/crypto/eel/modes/ecb_target.e new file mode 100644 index 00000000..bf03aa63 --- /dev/null +++ b/library/crypto/eel/modes/ecb_target.e @@ -0,0 +1,41 @@ +note + description: "A block cipher that can be the target of ECB mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "A government that is big enough to give you all you want is big enough to take it all away. - Barry Goldwater (1964)" + +deferred class + ECB_TARGET + +feature + block_size: INTEGER_32 + deferred + ensure + Result > 0 + end + + ecb_ready: BOOLEAN + deferred + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ecb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ecb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end +end diff --git a/library/crypto/eel/modes/mode_test_data.e b/library/crypto/eel/modes/mode_test_data.e new file mode 100644 index 00000000..b14afae2 --- /dev/null +++ b/library/crypto/eel/modes/mode_test_data.e @@ -0,0 +1,45 @@ +note + description: "Summary description for {MODE_TEST_DATA}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The only thing necessary for evil to triumph is for good men to do nothing. - Edmund Burke" + +deferred class + MODE_TEST_DATA + +feature + make_data + local + block_1_text: INTEGER_X + block_2_text: INTEGER_X + block_3_text: INTEGER_X + block_4_text: INTEGER_X + iv_text: INTEGER_X + do + create block_1_text.make_from_hex_string ("6bc1bee22e409f96e93d7e117393172a") + create block_1.make_filled (0, 16) + block_1_text.to_fixed_width_byte_array (block_1, 0, 15) + create block_2_text.make_from_hex_string ("ae2d8a571e03ac9c9eb76fac45af8e51") + create block_2.make_filled (0, 16) + block_2_text.to_fixed_width_byte_array (block_2, 0, 15) + create block_3_text.make_from_hex_string ("30c81c46a35ce411e5fbc1191a0a52ef") + create block_3.make_filled (0, 16) + block_3_text.to_fixed_width_byte_array (block_3, 0, 15) + create block_4_text.make_from_hex_string ("f69f2445df4f9b17ad2b417be66c3710") + create block_4.make_filled (0, 16) + block_4_text.to_fixed_width_byte_array (block_4, 0, 15) + create iv_text.make_from_hex_string ("000102030405060708090a0b0c0d0e0f") + create iv.make_filled (0, 16) + iv_text.to_fixed_width_byte_array (iv, 0, 15) + create iv_counter.make_from_hex_string ("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") + end + + block_1: SPECIAL [NATURAL_8] + block_2: SPECIAL [NATURAL_8] + block_3: SPECIAL [NATURAL_8] + block_4: SPECIAL [NATURAL_8] + + iv: SPECIAL [NATURAL_8] + iv_counter: INTEGER_X +end diff --git a/library/crypto/eel/modes/ofb_decryption.e b/library/crypto/eel/modes/ofb_decryption.e new file mode 100644 index 00000000..19e2c000 --- /dev/null +++ b/library/crypto/eel/modes/ofb_decryption.e @@ -0,0 +1,55 @@ +note + description: "Output Feedback decryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Sometimes it is said that man cannot be trusted with the government of himself. Can he, then, be trusted with the government of others? - Thomas Jefferson (1801)" + +class + OFB_DECRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: OFB_TARGET iv: SPECIAL [NATURAL_8] iv_offset: INTEGER_32) + require + iv.valid_index (iv_offset) + iv.valid_index (iv_offset + target_a.block_size - 1) + do + target := target_a + create last.make_filled (0, block_size) + last.copy_data (iv, iv_offset, 0, block_size) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + decrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ofb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + target.encrypt_block (last, 0, out_array, out_offset) + last.copy_data (out_array, out_offset, 0, block_size) + array_xor (last, 0, in, in_offset, out_array, out_offset, block_size) + end + + ofb_ready: BOOLEAN + do + result := target.ofb_ready + end + +feature {NONE} + last: SPECIAL [NATURAL_8] + target: OFB_TARGET +end diff --git a/library/crypto/eel/modes/ofb_encryption.e b/library/crypto/eel/modes/ofb_encryption.e new file mode 100644 index 00000000..5a050c80 --- /dev/null +++ b/library/crypto/eel/modes/ofb_encryption.e @@ -0,0 +1,55 @@ +note + description: "Output Feedback encryption mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Power tends to corrupt, and absolute power corrupts absolutely. - Lord Acton (1887)" + +class + OFB_ENCRYPTION + +inherit + ARRAY_FACILITIES + +create + make + +feature + make (target_a: OFB_TARGET iv: SPECIAL [NATURAL_8] iv_offset: INTEGER_32) + require + iv.valid_index (iv_offset) + iv.valid_index (iv_offset + target_a.block_size - 1) + do + target := target_a + create last.make_filled (0, block_size) + last.copy_data (iv, iv_offset, 0, block_size) + end + +feature + block_size: INTEGER_32 + do + result := target.block_size + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ofb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + do + target.encrypt_block (last, 0, out_array, out_offset) + last.copy_data (out_array, out_offset, 0, block_size) + array_xor (last, 0, in, in_offset, out_array, out_offset, block_size) + end + + ofb_ready: BOOLEAN + do + result := target.ofb_ready + end + +feature {NONE} + last: SPECIAL [NATURAL_8] + target: OFB_TARGET +end diff --git a/library/crypto/eel/modes/ofb_target.e b/library/crypto/eel/modes/ofb_target.e new file mode 100644 index 00000000..4ee68244 --- /dev/null +++ b/library/crypto/eel/modes/ofb_target.e @@ -0,0 +1,31 @@ +note + description: "A block cipher that can be the target of OFB mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Political power grows out of the barrel of a gun. - Mao Zedong (1938)" + +deferred class + OFB_TARGET + +feature + block_size: INTEGER_32 + deferred + ensure + Result > 0 + end + + ofb_ready: BOOLEAN + deferred + end + + encrypt_block (in: SPECIAL [NATURAL_8] in_offset: INTEGER_32 out_array: SPECIAL [NATURAL_8] out_offset: INTEGER_32) + require + ofb_ready + in.valid_index (in_offset) + in.valid_index (in_offset + block_size - 1) + out_array.valid_index (out_offset) + out_array.valid_index (out_offset + block_size - 1) + deferred + end +end diff --git a/library/crypto/eel/preferences.wb b/library/crypto/eel/preferences.wb new file mode 100644 index 00000000..a3c0694f --- /dev/null +++ b/library/crypto/eel/preferences.wb @@ -0,0 +1 @@ +Favorites() \ No newline at end of file diff --git a/library/crypto/eel/rotate_facilities.e b/library/crypto/eel/rotate_facilities.e new file mode 100644 index 00000000..803a48e1 --- /dev/null +++ b/library/crypto/eel/rotate_facilities.e @@ -0,0 +1,31 @@ +note + description: "Provides facilities to rotate integers" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The more corrupt the state, the more it legislates. - Tacitus" + +deferred class + ROTATE_FACILITIES + +feature + rotate_right_32 (in: NATURAL_32 count: INTEGER_32): NATURAL_32 + require + count_too_small: count >= 0 + count_too_big: count <= 32 + do + result := (in |>> count) | (in |<< (32 - count)) + ensure + rotate_definition: result = (in |>> count) | (in |<< (32 - count)) + end + + rotate_left_32 (in: NATURAL_32 count: INTEGER_32): NATURAL_32 + require + count_too_small: count >= 0 + count_too_big: count <= 32 + do + result := (in |<< count) | (in |>> (32 - count)) + ensure + rotate_definition: result = (in |<< count) | (in |>> (32 - count)) + end +end diff --git a/library/crypto/eel/tests/aes_test.e b/library/crypto/eel/tests/aes_test.e new file mode 100644 index 00000000..b942d7e6 --- /dev/null +++ b/library/crypto/eel/tests/aes_test.e @@ -0,0 +1,250 @@ +note + description: "Objects that ..." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The best government is the one that charges you the least blackmail for leaving you alone. - Thomas Rudmose-Brown (1996)" + +class + AES_TEST + +inherit + EQA_TEST_SET + +feature + test_vector_256 + local + key_data: SPECIAL [NATURAL_8] + key: AES_KEY + cipher_text: SPECIAL [NATURAL_8] + plain: SPECIAL [NATURAL_8] + vector: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create key_data.make_filled (0, 32) + key_data [0] := 0x00 + key_data [1] := 0x01 + key_data [2] := 0x02 + key_data [3] := 0x03 + key_data [4] := 0x04 + key_data [5] := 0x05 + key_data [6] := 0x06 + key_data [7] := 0x07 + key_data [8] := 0x08 + key_data [9] := 0x09 + key_data [10] := 0x0a + key_data [11] := 0x0b + key_data [12] := 0x0c + key_data [13] := 0x0d + key_data [14] := 0x0e + key_data [15] := 0x0f + key_data [16] := 0x10 + key_data [17] := 0x11 + key_data [18] := 0x12 + key_data [19] := 0x13 + key_data [20] := 0x14 + key_data [21] := 0x15 + key_data [22] := 0x16 + key_data [23] := 0x17 + key_data [24] := 0x18 + key_data [25] := 0x19 + key_data [26] := 0x1a + key_data [27] := 0x1b + key_data [28] := 0x1c + key_data [29] := 0x1d + key_data [30] := 0x1e + key_data [31] := 0x1f + create key.make (key_data) + create solution.make_filled (0, 16) + solution [0] := 0x8e + solution [1] := 0xa2 + solution [2] := 0xb7 + solution [3] := 0xca + solution [4] := 0x51 + solution [5] := 0x67 + solution [6] := 0x45 + solution [7] := 0xbf + solution [8] := 0xea + solution [9] := 0xfc + solution [10] := 0x49 + solution [11] := 0x90 + solution [12] := 0x4b + solution [13] := 0x49 + solution [14] := 0x60 + solution [15] := 0x89 + create vector.make_filled (0, 16) + vector [0] := 0x00 + vector [1] := 0x11 + vector [2] := 0x22 + vector [3] := 0x33 + vector [4] := 0x44 + vector [5] := 0x55 + vector [6] := 0x66 + vector [7] := 0x77 + vector [8] := 0x88 + vector [9] := 0x99 + vector [10] := 0xaa + vector [11] := 0xbb + vector [12] := 0xcc + vector [13] := 0xdd + vector [14] := 0xee + vector [15] := 0xff + create cipher_text.make_filled (0, 16) + key.encrypt (vector, 0, cipher_text, 0) + correct := cipher_text.same_items (solution, 0, 0, 16) + assert ("test vector 256 1", correct) + create plain.make_filled (0, 16) + key.decrypt (cipher_text, 0, plain, 0) + correct := plain.same_items (vector, 0, 0, 16) + assert ("test vector 256 2", correct) + end + + test_vector_192 + local + key_data: SPECIAL [NATURAL_8] + key: AES_KEY + cipher_text: SPECIAL [NATURAL_8] + plain: SPECIAL [NATURAL_8] + vector: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create key_data.make_filled (0, 24) + key_data [0] := 0x00 + key_data [1] := 0x01 + key_data [2] := 0x02 + key_data [3] := 0x03 + key_data [4] := 0x04 + key_data [5] := 0x05 + key_data [6] := 0x06 + key_data [7] := 0x07 + key_data [8] := 0x08 + key_data [9] := 0x09 + key_data [10] := 0x0a + key_data [11] := 0x0b + key_data [12] := 0x0c + key_data [13] := 0x0d + key_data [14] := 0x0e + key_data [15] := 0x0f + key_data [16] := 0x10 + key_data [17] := 0x11 + key_data [18] := 0x12 + key_data [19] := 0x13 + key_data [20] := 0x14 + key_data [21] := 0x15 + key_data [22] := 0x16 + key_data [23] := 0x17 + create key.make (key_data) + create solution.make_filled (0, 16) + solution [0] := 0xdd + solution [1] := 0xa9 + solution [2] := 0x7c + solution [3] := 0xa4 + solution [4] := 0x86 + solution [5] := 0x4c + solution [6] := 0xdf + solution [7] := 0xe0 + solution [8] := 0x6e + solution [9] := 0xaf + solution [10] := 0x70 + solution [11] := 0xa0 + solution [12] := 0xec + solution [13] := 0x0d + solution [14] := 0x71 + solution [15] := 0x91 + create vector.make_filled (0, 16) + vector [0] := 0x00 + vector [1] := 0x11 + vector [2] := 0x22 + vector [3] := 0x33 + vector [4] := 0x44 + vector [5] := 0x55 + vector [6] := 0x66 + vector [7] := 0x77 + vector [8] := 0x88 + vector [9] := 0x99 + vector [10] := 0xaa + vector [11] := 0xbb + vector [12] := 0xcc + vector [13] := 0xdd + vector [14] := 0xee + vector [15] := 0xff + create cipher_text.make_filled (0, 16) + key.encrypt (vector, 0, cipher_text, 0) + correct := cipher_text.same_items (solution, 0, 0, 16) + assert ("test vector 192 1", correct) + create plain.make_filled (0, 16) + key.decrypt (cipher_text, 0, plain, 0) + correct := vector.same_items (plain, 0, 0, 16) + assert ("test vector 192 2", correct) + end + + test_vector_128 + local + aes: AES_KEY + cipher_text: SPECIAL [NATURAL_8] + plain: SPECIAL [NATURAL_8] + vector_1: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create solution.make_filled (0, 16) + solution [0] := 0x39 + solution [1] := 0x25 + solution [2] := 0x84 + solution [3] := 0x1d + solution [4] := 0x02 + solution [5] := 0xdc + solution [6] := 0x09 + solution [7] := 0xfb + solution [8] := 0xdc + solution [9] := 0x11 + solution [10] := 0x85 + solution [11] := 0x97 + solution [12] := 0x19 + solution [13] := 0x6a + solution [14] := 0x0b + solution [15] := 0x32 + create vector_1.make_filled (0, 16) + vector_1 [0] := 0x32 + vector_1 [1] := 0x43 + vector_1 [2] := 0xf6 + vector_1 [3] := 0xa8 + vector_1 [4] := 0x88 + vector_1 [5] := 0x5a + vector_1 [6] := 0x30 + vector_1 [7] := 0x8d + vector_1 [8] := 0x31 + vector_1 [9] := 0x31 + vector_1 [10] := 0x98 + vector_1 [11] := 0xa2 + vector_1 [12] := 0xe0 + vector_1 [13] := 0x37 + vector_1 [14] := 0x07 + vector_1 [15] := 0x34 + create cipher_text.make_filled (0, 16) + aes.encrypt (vector_1, 0, cipher_text, 0) + correct := cipher_text.same_items (solution, 0, 0, 16) + assert ("test vector 128 1", correct) + create plain.make_filled (0, 16) + aes.decrypt (cipher_text, 0, plain, 0) + correct := vector_1.same_items (plain, 0, 0, 16) + assert ("test vector 128 2", correct) + end + + test_keys + local + key1: AES_KEY + key2: AES_KEY + key3: AES_KEY + do + create key1.make_spec_128 + assert ("test keys 1", key1.spec_128_bit_schedule) + create key2.make_spec_196 + assert ("test keys 2", key2.spec_196_bit_schedule) + create key3.make_spec_256 + assert ("test keys 3", key3.spec_256_bit_schedule) + end +end diff --git a/library/crypto/eel/tests/cbc_test.e b/library/crypto/eel/tests/cbc_test.e new file mode 100644 index 00000000..6ff7319c --- /dev/null +++ b/library/crypto/eel/tests/cbc_test.e @@ -0,0 +1,226 @@ +note + description: "Tests Cipher Block Chaining mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Government is the great fiction, through which everybody endeavors to live at the expense of everybody else. - Frederic Bastiat" + +class + CBC_TEST + +inherit + MODE_TEST_DATA + undefine + default_create + end + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} + on_prepare + local + ciphertext: INTEGER_X + do + make_data + create ciphertext.make_from_hex_string ("7649abac8119b246cee98e9b12e9197d") + create ciphertext_1_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128, 0, 15) + create ciphertext.make_from_hex_string ("5086cb9b507219ee95db113a917678b2") + create ciphertext_2_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128, 0, 15) + create ciphertext.make_from_hex_string ("73bed6b8e3c1743b7116e69e22229516") + create ciphertext_3_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128, 0, 15) + create ciphertext.make_from_hex_string ("3ff1caa1681fac09120eca307586e1a7") + create ciphertext_4_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128, 0, 15) + + create ciphertext.make_from_hex_string ("4f021db243bc633d7178183a9fa071e8") + create ciphertext_1_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_196, 0, 15) + create ciphertext.make_from_hex_string ("b4d9ada9ad7dedf4e5e738763f69145a") + create ciphertext_2_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_196, 0, 15) + create ciphertext.make_from_hex_string ("571b242012fb7ae07fa9baac3df102e0") + create ciphertext_3_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_196, 0, 15) + create ciphertext.make_from_hex_string ("08b0e27988598881d920a9e64f5615cd") + create ciphertext_4_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_196, 0, 15) + + create ciphertext.make_from_hex_string ("f58c4c04d6e5f1ba779eabfb5f7bfbd6") + create ciphertext_1_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_256, 0, 15) + create ciphertext.make_from_hex_string ("9cfc4e967edb808d679f777bc6702c7d") + create ciphertext_2_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_256, 0, 15) + create ciphertext.make_from_hex_string ("39f23369a9d9bacfa530e26304231461") + create ciphertext_3_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_256, 0, 15) + create ciphertext.make_from_hex_string ("b2eb05e2c39be9fcda6c19078c6a9d1b") + create ciphertext_4_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_256, 0, 15) + end + +feature + ciphertext_1_128: SPECIAL [NATURAL_8] + ciphertext_2_128: SPECIAL [NATURAL_8] + ciphertext_3_128: SPECIAL [NATURAL_8] + ciphertext_4_128: SPECIAL [NATURAL_8] + + ciphertext_1_196: SPECIAL [NATURAL_8] + ciphertext_2_196: SPECIAL [NATURAL_8] + ciphertext_3_196: SPECIAL [NATURAL_8] + ciphertext_4_196: SPECIAL [NATURAL_8] + + ciphertext_1_256: SPECIAL [NATURAL_8] + ciphertext_2_256: SPECIAL [NATURAL_8] + ciphertext_3_256: SPECIAL [NATURAL_8] + ciphertext_4_256: SPECIAL [NATURAL_8] + + test_encryption_128 + local + cbc: CBC_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create ciphertext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128, 0, 0, 16) + assert ("test encryption 128 1", correct) + cbc.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128, 0, 0, 16) + assert ("test encryption 128 2", correct) + cbc.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128, 0, 0, 16) + assert ("test encryption 128 3", correct) + cbc.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128, 0, 0, 16) + assert ("test encryption 128 4", correct) + end + + test_decryption_128 + local + cbc: CBC_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create plaintext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.decrypt_block (ciphertext_1_128, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 1", correct) + cbc.decrypt_block (ciphertext_2_128, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 2", correct) + cbc.decrypt_block (ciphertext_3_128, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 3", correct) + cbc.decrypt_block (ciphertext_4_128, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 4", correct) + end + + test_encryption_196 + local + cbc: CBC_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create ciphertext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_196, 0, 0, 16) + assert ("test encryption 196 1", correct) + cbc.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_196, 0, 0, 16) + assert ("test encryption 196 2", correct) + cbc.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_196, 0, 0, 16) + assert ("test encryption 196 3", correct) + cbc.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_196, 0, 0, 16) + assert ("test encryption 196 4", correct) + end + + test_decryption_196 + local + cbc: CBC_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create plaintext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.decrypt_block (ciphertext_1_196, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 196 1", correct) + cbc.decrypt_block (ciphertext_2_196, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 196 2", correct) + cbc.decrypt_block (ciphertext_3_196, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 196 3", correct) + cbc.decrypt_block (ciphertext_4_196, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 196 4", correct) + end + + test_encryption_256 + local + cbc: CBC_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create ciphertext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_256, 0, 0, 16) + assert ("test encryption 256 1", correct) + cbc.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_256, 0, 0, 16) + assert ("test encryption 256 2", correct) + cbc.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_256, 0, 0, 16) + assert ("test encryption 256 3", correct) + cbc.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_256, 0, 0, 16) + assert ("test encryption 256 4", correct) + end + + test_decryption_256 + local + cbc: CBC_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create plaintext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.decrypt_block (ciphertext_1_256, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 256 1", correct) + cbc.decrypt_block (ciphertext_2_256, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 256 2", correct) + cbc.decrypt_block (ciphertext_3_256, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 256 3", correct) + cbc.decrypt_block (ciphertext_4_256, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 256 4", correct) + end +end diff --git a/library/crypto/eel/tests/cfb_test.e b/library/crypto/eel/tests/cfb_test.e new file mode 100644 index 00000000..5dd31e69 --- /dev/null +++ b/library/crypto/eel/tests/cfb_test.e @@ -0,0 +1,226 @@ +note + description: "Tests Cipher Feedback mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Liberty is the only thing you cannot have unless you are willing to give it to others. - William Allen White" + +class + CFB_TEST + +inherit + MODE_TEST_DATA + undefine + default_create + end + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} + on_prepare + local + ciphertext: INTEGER_X + do + make_data + create ciphertext.make_from_hex_string ("3b3fd92eb72dad20333449f8e83cfb4a") + create ciphertext_1_128_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128_128, 0, 15) + create ciphertext.make_from_hex_string ("c8a64537a0b3a93fcde3cdad9f1ce58b") + create ciphertext_2_128_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128_128, 0, 15) + create ciphertext.make_from_hex_string ("26751f67a3cbb140b1808cf187a4f4df") + create ciphertext_3_128_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128_128, 0, 15) + create ciphertext.make_from_hex_string ("c04b05357c5d1c0eeac4c66f9ff7f2e6") + create ciphertext_4_128_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128_128, 0, 15) + + create ciphertext.make_from_hex_string ("cdc80d6fddf18cab34c25909c99a4174") + create ciphertext_1_128_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128_196, 0, 15) + create ciphertext.make_from_hex_string ("67ce7f7f81173621961a2b70171d3d7a") + create ciphertext_2_128_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128_196, 0, 15) + create ciphertext.make_from_hex_string ("2e1e8a1dd59b88b1c8e60fed1efac4c9") + create ciphertext_3_128_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128_196, 0, 15) + create ciphertext.make_from_hex_string ("c05f9f9ca9834fa042ae8fba584b09ff") + create ciphertext_4_128_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128_196, 0, 15) + + create ciphertext.make_from_hex_string ("dc7e84bfda79164b7ecd8486985d3860") + create ciphertext_1_128_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128_256, 0, 15) + create ciphertext.make_from_hex_string ("39ffed143b28b1c832113c6331e5407b") + create ciphertext_2_128_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128_256, 0, 15) + create ciphertext.make_from_hex_string ("df10132415e54b92a13ed0a8267ae2f9") + create ciphertext_3_128_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128_256, 0, 15) + create ciphertext.make_from_hex_string ("75a385741ab9cef82031623d55b1e471") + create ciphertext_4_128_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128_256, 0, 15) + end + +feature + ciphertext_1_128_128: SPECIAL [NATURAL_8] + ciphertext_2_128_128: SPECIAL [NATURAL_8] + ciphertext_3_128_128: SPECIAL [NATURAL_8] + ciphertext_4_128_128: SPECIAL [NATURAL_8] + + ciphertext_1_128_196: SPECIAL [NATURAL_8] + ciphertext_2_128_196: SPECIAL [NATURAL_8] + ciphertext_3_128_196: SPECIAL [NATURAL_8] + ciphertext_4_128_196: SPECIAL [NATURAL_8] + + ciphertext_1_128_256: SPECIAL [NATURAL_8] + ciphertext_2_128_256: SPECIAL [NATURAL_8] + ciphertext_3_128_256: SPECIAL [NATURAL_8] + ciphertext_4_128_256: SPECIAL [NATURAL_8] + + test_encryption_128_128 + local + cfb: CFB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create ciphertext.make_filled (0, 16) + create cfb.make (aes, iv, 0, 16) + cfb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128_128, 0, 0, 16) + assert ("test encryption 128 128 1", correct) + cfb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128_128, 0, 0, 16) + assert ("test encryption 128 128 2", correct) + cfb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128_128, 0, 0, 16) + assert ("test encryption 128 128 3", correct) + cfb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128_128, 0, 0, 16) + assert ("test encryption 128 128 4", correct) + end + + test_decryption_128_128 + local + cfb: CFB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create plaintext.make_filled (0, 16) + create cfb.make (aes, iv, 0, 16) + cfb.decrypt_block (ciphertext_1_128_128, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 128 1", correct) + cfb.decrypt_block (ciphertext_2_128_128, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 128 2", correct) + cfb.decrypt_block (ciphertext_3_128_128, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 128 3", correct) + cfb.decrypt_block (ciphertext_4_128_128, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 128 4", correct) + end + + test_encryption_128_196 + local + cfb: CFB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create ciphertext.make_filled (0, 16) + create cfb.make (aes, iv, 0, 16) + cfb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128_196, 0, 0, 16) + assert ("test encryption 128 196 1", correct) + cfb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128_196, 0, 0, 16) + assert ("test encryption 128 196 2", correct) + cfb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128_196, 0, 0, 16) + assert ("test encryption 128 196 3", correct) + cfb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128_196, 0, 0, 16) + assert ("test encryption 128 196 4", correct) + end + + test_decryption_128_196 + local + cfb: CFB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create plaintext.make_filled (0, 16) + create cfb.make (aes, iv, 0, 16) + cfb.decrypt_block (ciphertext_1_128_196, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 196 1", correct) + cfb.decrypt_block (ciphertext_2_128_196, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 196 2", correct) + cfb.decrypt_block (ciphertext_3_128_196, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 196 3", correct) + cfb.decrypt_block (ciphertext_4_128_196, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 196 4", correct) + end + + test_encryption_128_256 + local + cfb: CFB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create ciphertext.make_filled (0, 16) + create cfb.make (aes, iv, 0, 16) + cfb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128_256, 0, 0, 16) + assert ("test encryption 128 256 1", correct) + cfb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128_256, 0, 0, 16) + assert ("test encryption 128 256 2", correct) + cfb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128_256, 0, 0, 16) + assert ("test encryption 128 256 3", correct) + cfb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128_256, 0, 0, 16) + assert ("test encryption 128 256 4", correct) + end + + test_decryption_128_256 + local + cfb: CFB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create plaintext.make_filled (0, 16) + create cfb.make (aes, iv, 0, 16) + cfb.decrypt_block (ciphertext_1_128_256, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 256 1", correct) + cfb.decrypt_block (ciphertext_2_128_256, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 256 2", correct) + cfb.decrypt_block (ciphertext_3_128_256, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 256 3", correct) + cfb.decrypt_block (ciphertext_4_128_256, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 256 4", correct) + end +end diff --git a/library/crypto/eel/tests/ctr_test.e b/library/crypto/eel/tests/ctr_test.e new file mode 100644 index 00000000..f97a1877 --- /dev/null +++ b/library/crypto/eel/tests/ctr_test.e @@ -0,0 +1,226 @@ +note + description: "Tests Counter mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "We contend that for a nation to try to tax itself into prosperity is like a man standing in a bucket and trying to lift himself up by the handle. - Winston Churchill (1903)" + +class + CTR_TEST + +inherit + MODE_TEST_DATA + undefine + default_create + end + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} + on_prepare + local + ciphertext: INTEGER_X + do + make_data + create ciphertext.make_from_hex_string ("874d6191b620e3261bef6864990db6ce") + create ciphertext_1_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128, 0, 15) + create ciphertext.make_from_hex_string ("9806f66b7970fdff8617187bb9fffdff") + create ciphertext_2_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128, 0, 15) + create ciphertext.make_from_hex_string ("5ae4df3edbd5d35e5b4f09020db03eab") + create ciphertext_3_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128, 0, 15) + create ciphertext.make_from_hex_string ("1e031dda2fbe03d1792170a0f3009cee") + create ciphertext_4_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128, 0, 15) + + create ciphertext.make_from_hex_string ("1abc932417521ca24f2b0459fe7e6e0b") + create ciphertext_1_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_196, 0, 15) + create ciphertext.make_from_hex_string ("090339ec0aa6faefd5ccc2c6f4ce8e94") + create ciphertext_2_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_196, 0, 15) + create ciphertext.make_from_hex_string ("1e36b26bd1ebc670d1bd1d665620abf7") + create ciphertext_3_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_196, 0, 15) + create ciphertext.make_from_hex_string ("4f78a7f6d29809585a97daec58c6b050") + create ciphertext_4_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_196, 0, 15) + + create ciphertext.make_from_hex_string ("601ec313775789a5b7a7f504bbf3d228") + create ciphertext_1_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_256, 0, 15) + create ciphertext.make_from_hex_string ("f443e3ca4d62b59aca84e990cacaf5c5") + create ciphertext_2_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_256, 0, 15) + create ciphertext.make_from_hex_string ("2b0930daa23de94ce87017ba2d84988d") + create ciphertext_3_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_256, 0, 15) + create ciphertext.make_from_hex_string ("dfc9c58db67aada613c2dd08457941a6") + create ciphertext_4_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_256, 0, 15) + end + +feature + ciphertext_1_128: SPECIAL [NATURAL_8] + ciphertext_2_128: SPECIAL [NATURAL_8] + ciphertext_3_128: SPECIAL [NATURAL_8] + ciphertext_4_128: SPECIAL [NATURAL_8] + + ciphertext_1_196: SPECIAL [NATURAL_8] + ciphertext_2_196: SPECIAL [NATURAL_8] + ciphertext_3_196: SPECIAL [NATURAL_8] + ciphertext_4_196: SPECIAL [NATURAL_8] + + ciphertext_1_256: SPECIAL [NATURAL_8] + ciphertext_2_256: SPECIAL [NATURAL_8] + ciphertext_3_256: SPECIAL [NATURAL_8] + ciphertext_4_256: SPECIAL [NATURAL_8] + + test_encryption_128 + local + ctr: CTR_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create ciphertext.make_filled (0, 16) + create ctr.make (aes, iv_counter) + ctr.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128, 0, 0, 16) + assert ("test encryption 128 1", correct) + ctr.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128, 0, 0, 16) + assert ("test encryption 128 2", correct) + ctr.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128, 0, 0, 16) + assert ("test encryption 128 3", correct) + ctr.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128, 0, 0, 16) + assert ("test encryption 128 4", correct) + end + + test_decryption_128 + local + ctr: CTR_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create plaintext.make_filled (0, 16) + create ctr.make (aes, iv_counter) + ctr.decrypt_block (ciphertext_1_128, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 1", correct) + ctr.decrypt_block (ciphertext_2_128, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 2", correct) + ctr.decrypt_block (ciphertext_3_128, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 3", correct) + ctr.decrypt_block (ciphertext_4_128, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 4", correct) + end + + test_encryption_196 + local + ctr: CTR_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create ciphertext.make_filled (0, 16) + create ctr.make (aes, iv_counter) + ctr.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_196, 0, 0, 16) + assert ("test encryption 196 1", correct) + ctr.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_196, 0, 0, 16) + assert ("test encryption 196 2", correct) + ctr.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_196, 0, 0, 16) + assert ("test encryption 196 3", correct) + ctr.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_196, 0, 0, 16) + assert ("test encryption 196 4", correct) + end + + test_decryption_196 + local + ctr: CTR_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create plaintext.make_filled (0, 16) + create ctr.make (aes, iv_counter) + ctr.decrypt_block (ciphertext_1_196, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 196 1", correct) + ctr.decrypt_block (ciphertext_2_196, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 196 2", correct) + ctr.decrypt_block (ciphertext_3_196, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 196 3", correct) + ctr.decrypt_block (ciphertext_4_196, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 196 4", correct) + end + + test_encryption_256 + local + ctr: CTR_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create ciphertext.make_filled (0, 16) + create ctr.make (aes, iv_counter) + ctr.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_256, 0, 0, 16) + assert ("test encryption 256 1", correct) + ctr.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_256, 0, 0, 16) + assert ("test encryption 256 2", correct) + ctr.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_256, 0, 0, 16) + assert ("test encryption 256 3", correct) + ctr.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_256, 0, 0, 16) + assert ("test encryption 256 4", correct) + end + + test_decryption_256 + local + ctr: CTR_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create plaintext.make_filled (0, 16) + create ctr.make (aes, iv_counter) + ctr.decrypt_block (ciphertext_1_256, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 256 1", correct) + ctr.decrypt_block (ciphertext_2_256, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 256 2", correct) + ctr.decrypt_block (ciphertext_3_256, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 256 3", correct) + ctr.decrypt_block (ciphertext_4_256, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 256 4", correct) + end +end diff --git a/library/crypto/eel/tests/der_test.e b/library/crypto/eel/tests/der_test.e new file mode 100644 index 00000000..01449a70 --- /dev/null +++ b/library/crypto/eel/tests/der_test.e @@ -0,0 +1,52 @@ +note + description: "Tests DER encoding facilities" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Nothing can destroy a government more quickly than its failure to observe its own laws, or worse, its disregard of the charter of its own existence - U.S. Supreme Court Justice Tom C. Clark - Mapp vs. Ohio" + +class + DER_TEST + +inherit + DER_FACILITIES + undefine + default_create + end + + EQA_TEST_SET + +feature +-- test_big_int +-- local +-- int: INTEGER_X +-- sink: ARRAY_DER_SINK +-- target: ARRAY [NATURAL_8] +-- answer: ARRAY [NATURAL_8] +-- do +-- create int.make_from_hex_string ("02F40E7E 2221F295 DE297117 B7F3D62F 5C6A97FF CB8CEFF1 CD6BA8CE 4A9A18AD 84FFABBD 8EFA5933 2BE7AD67 56A66E29 4AFD185A 78FF12AA 520E4DE7 39BACA0C 7FFEFF7F 2955727A 02F40E7E 2221F295 DE297117 B7F3D62F 5C6A97FF CB8CEFF1 CD6BA8CE 4A9A18AD 84FFABBD 8EFA5933 2BE7AD67 56A66E29 4AFD185A 78FF12AA 520E4DE7 39BACA0C 7FFEFF7F 2955727A") +-- create target.make (1, 0) +-- create sink.make (target) +-- create answer.make (1, 1 + 1 + 4 + 36 * 4) +-- encode_integer (sink, int) +-- assert ("test big int 1", target.count = answer.count) +-- assert ("test big int 2", target.same_items (answer)) +-- end + +-- test_small_int +-- local +-- int: INTEGER_X +-- sink: ARRAY_DER_SINK +-- target: ARRAY [NATURAL_8] +-- answer: ARRAY [NATURAL_8] +-- do +-- create int.make_from_natural (0x738243) +-- create target.make (1, 0) +-- create sink.make (target) +-- create answer.make (1, 1 + 1 + 3) +-- answer [1] := 0x2 answer [2] := 0x3 answer [3] := 0x73 answer [4] := 0x82 answer [5] := 0x43 +-- encode_integer (sink, int) +-- assert ("test small int 1", target.count = answer.count) +-- assert ("test small int 2", target.same_items (answer)) +-- end +end diff --git a/library/crypto/eel/tests/ec_test.e b/library/crypto/eel/tests/ec_test.e new file mode 100644 index 00000000..1ba4ac8c --- /dev/null +++ b/library/crypto/eel/tests/ec_test.e @@ -0,0 +1,407 @@ +note + description : "Tests basic Elliptical Curve library functionality" + author : "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Giving money and power to government is like giving whiskey and car keys to teenage boys. - P.J. O'Rourke" + +class + EC_TEST + +inherit + EQA_TEST_SET + +feature -- Polynomial math + test_sec_multiply + local + curve: EC_CURVE_FP + g: EC_POINT_FP + d: INTEGER_X + q: EC_POINT_FP + q_x_solution: INTEGER_X + q_y_solution: INTEGER_X + q_solution: EC_POINT_FP + correct: BOOLEAN + do + create curve.make_sec_p160r1 + create g.make_sec_p160r1 + create d.make_from_hex_string ("AA374FFC 3CE144E6 B0733079 72CB6D57 B2A4E982") + q := g.product_value (d, curve) + create q_x_solution.make_from_string ("466448783855397898016055842232266600516272889280") + create q_y_solution.make_from_string ("1110706324081757720403272427311003102474457754220") + create q_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_FP}.make_p_x (q_x_solution), create {EC_FIELD_ELEMENT_FP}.make_p_x (q_y_solution)) + correct := q ~ q_solution + assert ("test sec multiply", correct) + end + + test_sec_sign + local + h: INTEGER_X + e: INTEGER_X + k: INTEGER_X + g: EC_POINT_FP + r: EC_POINT_FP + r_x_solution: INTEGER_X + r_y_solution: INTEGER_X + r_solution: EC_POINT_FP + curve: EC_CURVE_FP + correct: BOOLEAN + s: INTEGER_X + d: INTEGER_X + s_solution: INTEGER_X + n: INTEGER_X + do + create n.make_from_hex_string ("01 00000000 00000000 0001F4C8 F927AED3 CA752257") + create d.make_from_hex_string ("AA374FFC 3CE144E6 B0733079 72CB6D57 B2A4E982") + create h.make_from_hex_string ("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D") + create curve.make_sec_p160r1 + create g.make_sec_p160r1 + create k.make_from_string ("702232148019446860144825009548118511996283736794") + r := g.product_value (k, curve) + create r_x_solution.make_from_string ("1176954224688105769566774212902092897866168635793") + create r_y_solution.make_from_string ("1130322298812061698910820170565981471918861336822") + create r_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_FP}.make_p_x (r_x_solution), create {EC_FIELD_ELEMENT_FP}.make_p_x (r_y_solution)) + correct := r_solution ~ r + assert ("test sec sign 1", correct) + e := h + s := (k.inverse_value (n) * (e + d * r.x.x)) \\ n + create s_solution.make_from_string ("299742580584132926933316745664091704165278518100") + correct := s ~ s_solution + assert ("test sec sign 2", correct) + end + + test_set_verify + local + h: INTEGER_X + e: INTEGER_X + s: INTEGER_X + r: INTEGER_X + n: INTEGER_X + u1: INTEGER_X + u2: INTEGER_X + g: EC_POINT_FP + q: EC_POINT_FP + q_x: INTEGER_X + q_y: INTEGER_X + curve: EC_CURVE_FP + r_point: EC_POINT_FP + r_x_solution: INTEGER_X + r_y_solution: INTEGER_X + gu: EC_POINT_FP + gu_x_solution: INTEGER_X + gu_y_solution: INTEGER_X + qu: EC_POINT_FP + qu_x_solution: INTEGER_X + qu_y_solution: INTEGER_X + correct: BOOLEAN + v: INTEGER_X + u1_solution: INTEGER_X + u2_solution: INTEGER_X + do + create h.make_from_hex_string ("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D") + create n.make_from_hex_string ("01 00000000 00000000 0001F4C8 F927AED3 CA752257") + create g.make_sec_p160r1 + create r.make_from_string ("1176954224688105769566774212902092897866168635793") + create s.make_from_string ("299742580584132926933316745664091704165278518100") + create curve.make_sec_p160r1 + create q_x.make_from_string ("466448783855397898016055842232266600516272889280") + create q_y.make_from_string ("1110706324081757720403272427311003102474457754220") + create q.make_curve_x_y (create {EC_FIELD_ELEMENT_FP}.make_p_x (q_x), create {EC_FIELD_ELEMENT_FP}.make_p_x (q_y)) + create gu_x_solution.make_from_string ("559637225459801172484164154368876326912482639549") + create gu_y_solution.make_from_string ("1427364757892877133166464896740210315153233662312") + create qu_x_solution.make_from_string ("1096326382299378890940501642113021093797486469420") + create qu_y_solution.make_from_string ("1361206527591198621565826173236094337930170472426") + create r_x_solution.make_from_string ("1176954224688105769566774212902092897866168635793") + create r_y_solution.make_from_string ("1130322298812061698910820170565981471918861336822") + create u1_solution.make_from_string ("126492345237556041805390442445971246551226394866") + create u2_solution.make_from_string ("642136937233451268764953375477669732399252982122") + e := h + u1 := e * s.inverse_value (n) \\ n + correct := u1 ~ u1_solution + assert ("test set verify 1", correct) + u2 := r * s.inverse_value (n) \\ n + correct := u2 ~ u2_solution + assert ("test set verify 2", correct) + gu := g.product_value (u1, curve) + correct := gu.x.x ~ gu_x_solution + assert ("test set verify 3", correct) + correct := gu.y.x ~ gu_y_solution + assert ("test set verify 4", correct) + qu := q.product_value (u2, curve) + correct := qu.x.x ~ qu_x_solution + assert ("test set verify 5", correct) + correct := qu.y.x ~ qu_y_solution + assert ("test set verify 6", correct) + r_point := gu.plus_value (qu, curve) + correct := r_x_solution ~ r_point.x.x + assert ("test set verify 7", correct) + correct := r_y_solution ~ r_point.y.x + assert ("test set verify 8", correct) + v := r_point.x.x \\ n + correct := v ~ r + assert ("test set verify 9", correct) + end + +feature -- Prime reflexive tests + test_reflexive_2 + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + i: INTEGER + do + from + i := 0 + until + i > 10 + loop + create key.make_sec_p112r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test reflexive 2 iteration: " + i.out, correct) + i := i + 1 + end + end + + test_reflexive + local + key1: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create message.make_from_string ("968236873715988614170569073515315707566766479517") + create key1.make_p521 + signature := key1.private.sign (message) + correct := key1.public.verify (message, signature) + assert ("test reflexive", correct) + end + + test_sec_p112r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p112r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p112r1 reflexive", correct) + end + + test_sec_p112r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p112r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p112r2 reflexive", correct) + end + + test_sec_p128r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p128r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p128r1 reflexive", correct) + end + + test_sec_p128r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p128r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p128r2 reflexive", correct) + end + + test_sec_p160k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p160k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p160k1 reflexive", correct) + end + + test_sec_p160r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p160r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p160r1 reflexive", correct) + end + + test_sec_p160r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p160r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p160r2 reflexive", correct) + end + + test_sec_p192k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p192k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p192k1 reflexive", correct) + end + + test_sec_p192r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p192r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p192r1 reflexive", correct) + end + + test_sec_p224k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p224k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p224k1 reflexive", correct) + end + + test_sec_p224r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p224r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p224r1 reflexive", correct) + end + + test_sec_p256k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p256k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p256k1 reflexive", correct) + end + + test_sec_p256r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p256r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p256r1 reflexive", correct) + end + + test_sec_p384r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p384r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p384r1 reflexive", correct) + end + + test_sec_p521r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_p521r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec p521r1 relfexive", correct) + end + + test_agreement + local + key1: EC_KEY_PAIR + key2: EC_KEY_PAIR + e1_agreement: INTEGER_X + e2_agreement: INTEGER_X + correct: BOOLEAN + do + create key1.make_p521 + create key2.make_p521 + e1_agreement := key1.private.agreement (key2.public) + e2_agreement := key2.private.agreement (key1.public) + correct := e1_agreement ~ e2_agreement + assert ("test agreement", correct) + end +end diff --git a/library/crypto/eel/tests/ecb_test.e b/library/crypto/eel/tests/ecb_test.e new file mode 100644 index 00000000..1c096ec6 --- /dev/null +++ b/library/crypto/eel/tests/ecb_test.e @@ -0,0 +1,227 @@ +note + description: "Tests Electronic Codebook mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Ask not what you can do for your country; ask what your government is doing to you. - Joseph Sobran (1990)" + +class + ECB_TEST + +inherit + MODE_TEST_DATA + undefine + default_create + end + + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} + on_prepare + local + ciphertext: INTEGER_X + do + make_data + create ciphertext.make_from_hex_string ("3ad77bb40d7a3660a89ecaf32466ef97") + create ciphertext_1_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128, 0, 15) + create ciphertext.make_from_hex_string ("f5d3d58503b9699de785895a96fdbaaf") + create ciphertext_2_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128, 0, 15) + create ciphertext.make_from_hex_string ("43b1cd7f598ece23881b00e3ed030688") + create ciphertext_3_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128, 0, 15) + create ciphertext.make_from_hex_string ("7b0c785e27e8ad3f8223207104725dd4") + create ciphertext_4_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128, 0, 15) + + create ciphertext.make_from_hex_string ("bd334f1d6e45f25ff712a214571fa5cc") + create ciphertext_1_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_196, 0, 15) + create ciphertext.make_from_hex_string ("974104846d0ad3ad7734ecb3ecee4eef") + create ciphertext_2_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_196, 0, 15) + create ciphertext.make_from_hex_string ("ef7afd2270e2e60adce0ba2face6444e") + create ciphertext_3_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_196, 0, 15) + create ciphertext.make_from_hex_string ("9a4b41ba738d6c72fb16691603c18e0e") + create ciphertext_4_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_196, 0, 15) + + create ciphertext.make_from_hex_string ("f3eed1bdb5d2a03c064b5a7e3db181f8") + create ciphertext_1_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_256, 0, 15) + create ciphertext.make_from_hex_string ("591ccb10d410ed26dc5ba74a31362870") + create ciphertext_2_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_256, 0, 15) + create ciphertext.make_from_hex_string ("b6ed21b99ca6f4f9f153e7b1beafed1d") + create ciphertext_3_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_256, 0, 15) + create ciphertext.make_from_hex_string ("23304b7a39f9f3ff067d8d8f9e24ecc7") + create ciphertext_4_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_256, 0, 15) + end + +feature + ciphertext_1_128: SPECIAL [NATURAL_8] + ciphertext_2_128: SPECIAL [NATURAL_8] + ciphertext_3_128: SPECIAL [NATURAL_8] + ciphertext_4_128: SPECIAL [NATURAL_8] + + ciphertext_1_196: SPECIAL [NATURAL_8] + ciphertext_2_196: SPECIAL [NATURAL_8] + ciphertext_3_196: SPECIAL [NATURAL_8] + ciphertext_4_196: SPECIAL [NATURAL_8] + + ciphertext_1_256: SPECIAL [NATURAL_8] + ciphertext_2_256: SPECIAL [NATURAL_8] + ciphertext_3_256: SPECIAL [NATURAL_8] + ciphertext_4_256: SPECIAL [NATURAL_8] + + test_encryption_128 + local + ecb: ECB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create ciphertext.make_filled (0, 16) + create ecb.make (aes) + ecb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128, 0, 0, 16) + assert ("test encryption 128 1", correct) + ecb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128, 0, 0, 16) + assert ("test encryption 128 2", correct) + ecb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128, 0, 0, 16) + assert ("test encryption 128 3", correct) + ecb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128, 0, 0, 16) + assert ("test encryption 128 4", correct) + end + + test_decryption_128 + local + ecb: ECB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create plaintext.make_filled (0, 16) + create ecb.make (aes) + ecb.decrypt_block (ciphertext_1_128, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 1", correct) + ecb.decrypt_block (ciphertext_2_128, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 2", correct) + ecb.decrypt_block (ciphertext_3_128, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 3", correct) + ecb.decrypt_block (ciphertext_4_128, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 4", correct) + end + + test_encryption_196 + local + ecb: ECB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create ciphertext.make_filled (0, 16) + create ecb.make (aes) + ecb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_196, 0, 0, 16) + assert ("test encryption 196 1", correct) + ecb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_196, 0, 0, 16) + assert ("test encryption 196 2", correct) + ecb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_196, 0, 0, 16) + assert ("test encryption 196 3", correct) + ecb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_196, 0, 0, 16) + assert ("test encryption 196 4", correct) + end + + test_decryption_196 + local + ecb: ECB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create plaintext.make_filled (0, 16) + create ecb.make (aes) + ecb.decrypt_block (ciphertext_1_196, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 196 1", correct) + ecb.decrypt_block (ciphertext_2_196, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 196 2", correct) + ecb.decrypt_block (ciphertext_3_196, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 196 3", correct) + ecb.decrypt_block (ciphertext_4_196, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 196 4", correct) + end + + test_encryption_256 + local + ecb: ECB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create ciphertext.make_filled (0, 16) + create ecb.make (aes) + ecb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_256, 0, 0, 16) + assert ("test encryption 256 1", correct) + ecb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_256, 0, 0, 16) + assert ("test encryption 256 2", correct) + ecb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_256, 0, 0, 16) + assert ("test encryption 256 3", correct) + ecb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_256, 0, 0, 16) + assert ("test encryption 256 4", correct) + end + + test_decryption_256 + local + ecb: ECB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create plaintext.make_filled (0, 16) + create ecb.make (aes) + ecb.decrypt_block (ciphertext_1_256, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 256 1", correct) + ecb.decrypt_block (ciphertext_2_256, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 256 2", correct) + ecb.decrypt_block (ciphertext_3_256, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 256 3", correct) + ecb.decrypt_block (ciphertext_4_256, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 256 4", correct) + end +end diff --git a/library/crypto/eel/tests/hmac_sha256_test.e b/library/crypto/eel/tests/hmac_sha256_test.e new file mode 100644 index 00000000..c249e256 --- /dev/null +++ b/library/crypto/eel/tests/hmac_sha256_test.e @@ -0,0 +1,110 @@ +note + description: "Summary description for {HMAC_SHA256_TEST}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + HMAC_SHA256_TEST + +inherit + + EQA_TEST_SET + +feature + + test_empty + local + hmac: HMAC_SHA256 + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("0")) + hmac.finish + hmac.reset + hmac.finish + end + + test_rfc_4231_1 + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")) + hmac.sink_string ("Hi There") + hmac.finish + create expected.make_from_hex_string ("b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7") + assert ("test_rfc_4231_1", hmac.hmac ~ expected) + end + + test_rfc_4231_2 + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("4a656665")) + hmac.sink_string ("what do ya want for nothing?") + hmac.finish + create expected.make_from_hex_string ("5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843") + assert ("test_rfc_4231_2", hmac.hmac ~ expected) + end + + test_rfc_4231_2_ascii + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make_ascii_key ("Jefe") + hmac.sink_string ("what do ya want for nothing?") + hmac.finish + create expected.make_from_hex_string ("5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843") + assert ("test_rfc_4231_2", hmac.hmac ~ expected) + end + + test_rfc_4231_3 + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) + hmac.sink_string (create {STRING_8}.make_filled ('%/221/', 50)) + hmac.finish + create expected.make_from_hex_string ("773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe") + assert ("test_rfc_4231_3", hmac.hmac ~ expected) + end + + test_rfc_4231_4 + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("0102030405060708090a0b0c0d0e0f10111213141516171819")) + hmac.sink_string (create {STRING_8}.make_filled ('%/205/', 50)) + hmac.finish + create expected.make_from_hex_string ("82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b") + assert ("test_rfc_4231_4", hmac.hmac ~ expected) + end + + test_rfc_4231_6 + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) + hmac.sink_string ("Test Using Larger Than Block-Size Key - Hash Key First") + hmac.finish + create expected.make_from_hex_string ("60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54") + assert ("test_rfc_4231_6", hmac.hmac ~ expected) + end + + test_rfc_4231_7 + local + hmac: HMAC_SHA256 + expected: INTEGER_X + do + create hmac.make (create {INTEGER_X}.make_from_hex_string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) + hmac.sink_string ("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.") + hmac.finish + create expected.make_from_hex_string ("9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2") + assert ("test_rfc_4231_7", hmac.hmac ~ expected) + end + +end diff --git a/library/crypto/eel/tests/md5_test.e b/library/crypto/eel/tests/md5_test.e new file mode 100644 index 00000000..d54c21ed --- /dev/null +++ b/library/crypto/eel/tests/md5_test.e @@ -0,0 +1,136 @@ +note + description: "Summary description for {MD5_TEST}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Give me liberty or give me death! - Patrick Henry" + +class + MD5_TEST + +inherit + EQA_TEST_SET + +feature + test_million_a + local + md5: MD5 + count: INTEGER_32 + do + create md5.make + from + count := 1 + until + count > 1_000_000 + loop + md5.sink_character ('a') + count := count + 1 + end + end + + test_alphabet + local + md5: MD5 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create solution.make_filled (0, 16) + solution [0] := 0xc3 + solution [1] := 0xfc + solution [2] := 0xd3 + solution [3] := 0xd7 + solution [4] := 0x61 + solution [5] := 0x92 + solution [6] := 0xe4 + solution [7] := 0x00 + solution [8] := 0x7d + solution [9] := 0xfb + solution [10] := 0x49 + solution [11] := 0x6c + solution [12] := 0xca + solution [13] := 0x67 + solution [14] := 0xe1 + solution [15] := 0x3b + create output.make_filled (0, 16) + create md5.make + md5.sink_string ("abcdefghijklmnopqrstuvwxyz") + md5.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 16) + assert ("test alphabet", correct) + end + + test_empty + local + md5: MD5 + output: SPECIAL [NATURAL_8] + do + create output.make_filled (0, 16) + create md5.make + md5.do_final (output, 0) + end + + test_a + local + md5: MD5 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create solution.make_filled (0, 16) + solution [0] := 0x0c + solution [1] := 0xc1 + solution [2] := 0x75 + solution [3] := 0xb9 + solution [4] := 0xc0 + solution [5] := 0xf1 + solution [6] := 0xb6 + solution [7] := 0xa8 + solution [8] := 0x31 + solution [9] := 0xc3 + solution [10] := 0x99 + solution [11] := 0xe2 + solution [12] := 0x69 + solution [13] := 0x77 + solution [14] := 0x26 + solution [15] := 0x61 + create output.make_filled (0, 16) + create md5.make + md5.sink_string ("a") + md5.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 16) + assert ("test a", correct) + end + + test_abc + local + md5: MD5 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create solution.make_filled (0, 16) + solution [0] := 0x90 + solution [1] := 0x01 + solution [2] := 0x50 + solution [3] := 0x98 + solution [4] := 0x3c + solution [5] := 0xd2 + solution [6] := 0x4f + solution [7] := 0xb0 + solution [8] := 0xd6 + solution [9] := 0x96 + solution [10] := 0x3f + solution [11] := 0x7d + solution [12] := 0x28 + solution [13] := 0xe1 + solution [14] := 0x7f + solution [15] := 0x72 + create output.make_filled (0, 16) + create md5.make + md5.sink_string ("abc") + md5.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 16) + assert ("test abc", correct) + end +end diff --git a/library/crypto/eel/tests/ofb_test.e b/library/crypto/eel/tests/ofb_test.e new file mode 100644 index 00000000..be05791f --- /dev/null +++ b/library/crypto/eel/tests/ofb_test.e @@ -0,0 +1,226 @@ +note + description: "Tests Output Feedback mode" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Government is actually the worst failure of civilized man. There has never been a really good one, and even those that are most tolerable are arbitrary, cruel, grasping, and unintelligent. - H. L. Mencken" + +class + OFB_TEST + +inherit + MODE_TEST_DATA + undefine + default_create + end + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} + on_prepare + local + ciphertext: INTEGER_X + do + make_data + create ciphertext.make_from_hex_string ("3b3fd92eb72dad20333449f8e83cfb4a") + create ciphertext_1_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_128, 0, 15) + create ciphertext.make_from_hex_string ("7789508d16918f03f53c52dac54ed825") + create ciphertext_2_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_128, 0, 15) + create ciphertext.make_from_hex_string ("9740051e9c5fecf64344f7a82260edcc") + create ciphertext_3_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_128, 0, 15) + create ciphertext.make_from_hex_string ("304c6528f659c77866a510d9c1d6ae5e") + create ciphertext_4_128.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_128, 0, 15) + + create ciphertext.make_from_hex_string ("cdc80d6fddf18cab34c25909c99a4174") + create ciphertext_1_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_196, 0, 15) + create ciphertext.make_from_hex_string ("fcc28b8d4c63837c09e81700c1100401") + create ciphertext_2_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_196, 0, 15) + create ciphertext.make_from_hex_string ("8d9a9aeac0f6596f559c6d4daf59a5f2") + create ciphertext_3_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_196, 0, 15) + create ciphertext.make_from_hex_string ("6d9f200857ca6c3e9cac524bd9acc92a") + create ciphertext_4_196.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_196, 0, 15) + + create ciphertext.make_from_hex_string ("dc7e84bfda79164b7ecd8486985d3860") + create ciphertext_1_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_1_256, 0, 15) + create ciphertext.make_from_hex_string ("4febdc6740d20b3ac88f6ad82a4fb08d") + create ciphertext_2_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_2_256, 0, 15) + create ciphertext.make_from_hex_string ("71ab47a086e86eedf39d1c5bba97c408") + create ciphertext_3_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_3_256, 0, 15) + create ciphertext.make_from_hex_string ("0126141d67f37be8538f5a8be740e484") + create ciphertext_4_256.make_filled (0, 16) + ciphertext.to_fixed_width_byte_array (ciphertext_4_256, 0, 15) + end + +feature + ciphertext_1_128: SPECIAL [NATURAL_8] + ciphertext_2_128: SPECIAL [NATURAL_8] + ciphertext_3_128: SPECIAL [NATURAL_8] + ciphertext_4_128: SPECIAL [NATURAL_8] + + ciphertext_1_196: SPECIAL [NATURAL_8] + ciphertext_2_196: SPECIAL [NATURAL_8] + ciphertext_3_196: SPECIAL [NATURAL_8] + ciphertext_4_196: SPECIAL [NATURAL_8] + + ciphertext_1_256: SPECIAL [NATURAL_8] + ciphertext_2_256: SPECIAL [NATURAL_8] + ciphertext_3_256: SPECIAL [NATURAL_8] + ciphertext_4_256: SPECIAL [NATURAL_8] + + test_encryption_128 + local + ofb: OFB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create ciphertext.make_filled (0, 16) + create ofb.make (aes, iv, 0) + ofb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_128, 0, 0, 16) + assert ("test encryption 128 1", correct) + ofb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_128, 0, 0, 16) + assert ("test encryption 128 2", correct) + ofb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_128, 0, 0, 16) + assert ("test encryption 128 3", correct) + ofb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_128, 0, 0, 16) + assert ("test encryption 128 4", correct) + end + + test_decryption_128 + local + ofb: OFB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_128 + create plaintext.make_filled (0, 16) + create ofb.make (aes, iv, 0) + ofb.decrypt_block (ciphertext_1_128, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 128 1", correct) + ofb.decrypt_block (ciphertext_2_128, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 128 2", correct) + ofb.decrypt_block (ciphertext_3_128, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 128 3", correct) + ofb.decrypt_block (ciphertext_4_128, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 128 4", correct) + end + + test_encryption_196 + local + ofb: OFB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create ciphertext.make_filled (0, 16) + create ofb.make (aes, iv, 0) + ofb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_196, 0, 0, 16) + assert ("test encryption 196 1", correct) + ofb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_196, 0, 0, 16) + assert ("test encryption 196 2", correct) + ofb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_196, 0, 0, 16) + assert ("test encryption 196 3", correct) + ofb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_196, 0, 0, 16) + assert ("test encryption 196 4", correct) + end + + test_decryption_196 + local + ofb: OFB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_196 + create plaintext.make_filled (0, 16) + create ofb.make (aes, iv, 0) + ofb.decrypt_block (ciphertext_1_196, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 196 1", correct) + ofb.decrypt_block (ciphertext_2_196, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 196 2", correct) + ofb.decrypt_block (ciphertext_3_196, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 196 3", correct) + ofb.decrypt_block (ciphertext_4_196, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 196 4", correct) + end + + test_encryption_256 + local + ofb: OFB_ENCRYPTION + aes: AES_KEY + ciphertext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create ciphertext.make_filled (0, 16) + create ofb.make (aes, iv, 0) + ofb.encrypt_block (block_1, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_1_256, 0, 0, 16) + assert ("test encryption 256 1", correct) + ofb.encrypt_block (block_2, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_2_256, 0, 0, 16) + assert ("test encryption 256 2", correct) + ofb.encrypt_block (block_3, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_3_256, 0, 0, 16) + assert ("test encryption 256 3", correct) + ofb.encrypt_block (block_4, 0, ciphertext, 0) + correct := ciphertext.same_items (ciphertext_4_256, 0, 0, 16) + assert ("test encryption 256 4", correct) + end + + test_decryption_256 + local + cbc: OFB_DECRYPTION + aes: AES_KEY + plaintext: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create aes.make_spec_256 + create plaintext.make_filled (0, 16) + create cbc.make (aes, iv, 0) + cbc.decrypt_block (ciphertext_1_256, 0, plaintext, 0) + correct := plaintext.same_items (block_1, 0, 0, 16) + assert ("test decryption 256 1", correct) + cbc.decrypt_block (ciphertext_2_256, 0, plaintext, 0) + correct := plaintext.same_items (block_2, 0, 0, 16) + assert ("test decryption 256 2", correct) + cbc.decrypt_block (ciphertext_3_256, 0, plaintext, 0) + correct := plaintext.same_items (block_3, 0, 0, 16) + assert ("test decryption 256 3", correct) + cbc.decrypt_block (ciphertext_4_256, 0, plaintext, 0) + correct := plaintext.same_items (block_4, 0, 0, 16) + assert ("test decryption 256 4", correct) + end +end diff --git a/library/crypto/eel/tests/rsa_test.e b/library/crypto/eel/tests/rsa_test.e new file mode 100644 index 00000000..a1ec4ccb --- /dev/null +++ b/library/crypto/eel/tests/rsa_test.e @@ -0,0 +1,89 @@ +note + description: "Summary description for {RSA_TEST}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "When buying and selling are controlled by legislation, the first things to be bought and sold are legislators. - P.J. O'Rourke" + +class + RSA_TEST + +inherit + EQA_TEST_SET + +feature + test_small + local + private: RSA_PRIVATE_KEY + public: RSA_PUBLIC_KEY + message: INTEGER_X + ciphertext: INTEGER_X + plaintext: INTEGER_X + do + create private.make (61, 53, 3233, 17) + create public.make (3233, 17) + assert ("test small 1", private.d.to_integer = 2753) + create message.make_from_integer (123) + ciphertext := public.encrypt (message) + assert ("test small 2", ciphertext.to_integer = 855) + plaintext := private.decrypt (ciphertext) + assert ("test small 3", plaintext.to_integer = 123) + end + + test_1024_reflexive + local + key_pair: RSA_KEY_PAIR + message: INTEGER_X + cipher: INTEGER_X + plain: INTEGER_X + signature: INTEGER_X + correct: BOOLEAN + do + create key_pair.make (1024) + create message.make_random (128) + cipher := key_pair.public.encrypt (message) + plain := key_pair.private.decrypt (cipher) + assert ("test 1024 reflexive 1", plain ~ message) + signature := key_pair.private.sign (message) + correct := key_pair.public.verify (message, signature) + assert ("test 1024 reflexive 2", correct) + end + + test_2048_reflexive + local + key_pair: RSA_KEY_PAIR + message: INTEGER_X + cipher: INTEGER_X + plain: INTEGER_X + signature: INTEGER_X + correct: BOOLEAN + do + create key_pair.make (2048) + create message.make_random (128) + cipher := key_pair.public.encrypt (message) + plain := key_pair.private.decrypt (cipher) + assert ("test 2048 reflexive 1", plain ~ message) + signature := key_pair.private.sign (message) + correct := key_pair.public.verify (message, signature) + assert ("test 2048 reflexive 2", correct) + end + + test_4096_reflexive + local + key_pair: RSA_KEY_PAIR + message: INTEGER_X + cipher: INTEGER_X + plain: INTEGER_X + signature: INTEGER_X + correct: BOOLEAN + do + create key_pair.make (4096) + create message.make_random (128) + cipher := key_pair.public.encrypt (message) + plain := key_pair.private.decrypt (cipher) + assert ("test 4096 reflexive 1", plain ~ message) + signature := key_pair.private.sign (message) + correct := key_pair.public.verify (message, signature) + assert ("test 4096 reflexive 2", correct) + end +end diff --git a/library/crypto/eel/tests/sha1_test.e b/library/crypto/eel/tests/sha1_test.e new file mode 100644 index 00000000..2b36e11a --- /dev/null +++ b/library/crypto/eel/tests/sha1_test.e @@ -0,0 +1,169 @@ +note + description: "Summary description for {SHA1_TEST}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "We must have government, but we must watch them like a hawk. - Millicent Fenwick (1983)" + +class + SHA1_TEST + +inherit + EQA_TEST_SET + +feature + test_long + local + sha1: SHA1 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + i: INTEGER + do + create sha1.make + create output.make_filled (0, 20) + create solution.make_filled (0, 20) + solution [0] := 0x34 + solution [1] := 0xaa + solution [2] := 0x97 + solution [3] := 0x3c + solution [4] := 0xd4 + solution [5] := 0xc4 + solution [6] := 0xda + solution [7] := 0xa4 + solution [8] := 0xf6 + solution [9] := 0x1e + solution [10] := 0xeb + solution [11] := 0x2b + solution [12] := 0xdb + solution [13] := 0xad + solution [14] := 0x27 + solution [15] := 0x31 + solution [16] := 0x65 + solution [17] := 0x34 + solution [18] := 0x01 + solution [19] := 0x6f + from + i := 1 + until + i > 1_000_000 + loop + sha1.sink_character ('a') + i := i + 1 + variant + 1_000_000 - i + 1 + end + sha1.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 20) + assert ("test long", correct) + end + + test_multi + local + sha1: SHA1 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create sha1.make + create output.make_filled (0, 20) + create solution.make_filled (0, 20) + solution [0] := 0x84 + solution [1] := 0x98 + solution [2] := 0x3e + solution [3] := 0x44 + solution [4] := 0x1c + solution [5] := 0x3b + solution [6] := 0xd2 + solution [7] := 0x6e + solution [8] := 0xba + solution [9] := 0xae + solution [10] := 0x4a + solution [11] := 0xa1 + solution [12] := 0xf9 + solution [13] := 0x51 + solution [14] := 0x29 + solution [15] := 0xe5 + solution [16] := 0xe5 + solution [17] := 0x46 + solution [18] := 0x70 + solution [19] := 0xf1 + sha1.sink_string ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") + sha1.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 20) + assert ("test multi", correct) + end + + test_abc + local + sha1: SHA1 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create sha1.make + create output.make_filled (0, 20) + create solution.make_filled (0, 20) + solution [0] := 0xa9 + solution [1] := 0x99 + solution [2] := 0x3e + solution [3] := 0x36 + solution [4] := 0x47 + solution [5] := 0x06 + solution [6] := 0x81 + solution [7] := 0x6a + solution [8] := 0xba + solution [9] := 0x3e + solution [10] := 0x25 + solution [11] := 0x71 + solution [12] := 0x78 + solution [13] := 0x50 + solution [14] := 0xc2 + solution [15] := 0x6c + solution [16] := 0x9c + solution [17] := 0xd0 + solution [18] := 0xd8 + solution [19] := 0x9d + sha1.update (('a').code.to_natural_8) + sha1.update (('b').code.to_natural_8) + sha1.update (('c').code.to_natural_8) + sha1.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 20) + assert ("test abc", correct) + end + + test_empty + local + sha1: SHA1 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create sha1.make + create output.make_filled (0, 20) + create solution.make_filled (0, 20) + solution [0] := 0xda + solution [1] := 0x39 + solution [2] := 0xa3 + solution [3] := 0xee + solution [4] := 0x5e + solution [5] := 0x6b + solution [6] := 0x4b + solution [7] := 0x0d + solution [8] := 0x32 + solution [9] := 0x55 + solution [10] := 0xbf + solution [11] := 0xef + solution [12] := 0x95 + solution [13] := 0x60 + solution [14] := 0x18 + solution [15] := 0x90 + solution [16] := 0xaf + solution [17] := 0xd8 + solution [18] := 0x07 + solution [19] := 0x09 + sha1.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 20) + assert ("test empty", correct) + end +end diff --git a/library/crypto/eel/tests/sha256_test.e b/library/crypto/eel/tests/sha256_test.e new file mode 100644 index 00000000..1ef14365 --- /dev/null +++ b/library/crypto/eel/tests/sha256_test.e @@ -0,0 +1,170 @@ +note + description: "Summary description for {SHA256_TEST}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "A little government and a little luck are necessary in life, but only a fool trusts either of them. - P. J. O'Rourke" + +class + SHA256_TEST + +inherit + EQA_TEST_SET + +feature + test_long + local + sha256: SHA256 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + i: INTEGER + do + create sha256.make + create output.make_filled (0, 32) + create solution.make_filled (0, 32) + solution [0] := 0xcd + solution [1] := 0xc7 + solution [2] := 0x6e + solution [3] := 0x5c + solution [4] := 0x99 + solution [5] := 0x14 + solution [6] := 0xfb + solution [7] := 0x92 + solution [8] := 0x81 + solution [9] := 0xa1 + solution [10] := 0xc7 + solution [11] := 0xe2 + solution [12] := 0x84 + solution [13] := 0xd7 + solution [14] := 0x3e + solution [15] := 0x67 + solution [16] := 0xf1 + solution [17] := 0x80 + solution [18] := 0x9a + solution [19] := 0x48 + solution [20] := 0xa4 + solution [21] := 0x97 + solution [22] := 0x20 + solution [23] := 0x0e + solution [24] := 0x04 + solution [25] := 0x6d + solution [26] := 0x39 + solution [27] := 0xcc + solution [28] := 0xc7 + solution [29] := 0x11 + solution [30] := 0x2c + solution [31] := 0xd0 + from + i := 1 + until + i > 1_000_000 + loop + sha256.sink_character ('a') + i := i + 1 + variant + 1_000_000 - i + 1 + end + sha256.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 32) + assert ("test long", correct) + end + + test_multi + local + sha256: SHA256 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create sha256.make + create output.make_filled (0, 32) + create solution.make_filled (0, 32) + solution [0] := 0x24 + solution [1] := 0x8d + solution [2] := 0x6a + solution [3] := 0x61 + solution [4] := 0xd2 + solution [5] := 0x06 + solution [6] := 0x38 + solution [7] := 0xb8 + solution [8] := 0xe5 + solution [9] := 0xc0 + solution [10] := 0x26 + solution [11] := 0x93 + solution [12] := 0x0c + solution [13] := 0x3e + solution [14] := 0x60 + solution [15] := 0x39 + solution [16] := 0xa3 + solution [17] := 0x3c + solution [18] := 0xe4 + solution [19] := 0x59 + solution [20] := 0x64 + solution [21] := 0xff + solution [22] := 0x21 + solution [23] := 0x67 + solution [24] := 0xf6 + solution [25] := 0xec + solution [26] := 0xed + solution [27] := 0xd4 + solution [28] := 0x19 + solution [29] := 0xdb + solution [30] := 0x06 + solution [31] := 0xc1 + sha256.sink_string ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") + sha256.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 32) + assert ("test multi", correct) + end + + test_abc + local + sha256: SHA256 + output: SPECIAL [NATURAL_8] + solution: SPECIAL [NATURAL_8] + correct: BOOLEAN + do + create sha256.make + create output.make_filled (0, 32) + create solution.make_filled (0, 32) + solution [0] := 0xba + solution [1] := 0x78 + solution [2] := 0x16 + solution [3] := 0xbf + solution [4] := 0x8f + solution [5] := 0x01 + solution [6] := 0xcf + solution [7] := 0xea + solution [8] := 0x41 + solution [9] := 0x41 + solution [10] := 0x40 + solution [11] := 0xde + solution [12] := 0x5d + solution [13] := 0xae + solution [14] := 0x22 + solution [15] := 0x23 + solution [16] := 0xb0 + solution [17] := 0x03 + solution [18] := 0x61 + solution [19] := 0xa3 + solution [20] := 0x96 + solution [21] := 0x17 + solution [22] := 0x7a + solution [23] := 0x9c + solution [24] := 0xb4 + solution [25] := 0x10 + solution [26] := 0xff + solution [27] := 0x61 + solution [28] := 0xf2 + solution [29] := 0x00 + solution [30] := 0x15 + solution [31] := 0xad + sha256.update (('a').code.to_natural_8) + sha256.update (('b').code.to_natural_8) + sha256.update (('c').code.to_natural_8) + sha256.do_final (output, 0) + correct := solution.same_items (output, 0, 0, 32) + assert ("test abc", correct) + end +end diff --git a/library/crypto/eel/tests/test.e b/library/crypto/eel/tests/test.e new file mode 100644 index 00000000..9b518d05 --- /dev/null +++ b/library/crypto/eel/tests/test.e @@ -0,0 +1,95 @@ +note + description : "tests application root class" + date : "$Date: 2008-12-29 15:41:59 -0800 (Mon, 29 Dec 2008) $" + revision : "$Revision: 76432 $" + +class + TEST + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + local + key_pair: RSA_KEY_PAIR + message: INTEGER_X + cipher: INTEGER_X + plain: INTEGER_X + signature: INTEGER_X + correct: BOOLEAN + do + io.put_string ("Creating keypair%N") + create key_pair.make (1024) + io.put_string ("Created keypair%N") + create message.make_random (128) + cipher := key_pair.public.encrypt (message) + plain := key_pair.private.decrypt (cipher) + io.put_string ("Checked encryption%N") + signature := key_pair.private.sign (message) + correct := key_pair.public.verify (message, signature) + io.put_string ("Checked signing%N") + end + + make_2 + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + i: INTEGER + do + create key.make_sec_t113r1 + create message.make_random_max (key.private.params.n) + from + i := 0 + until + i > 100 + loop + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + i := i + 1 + end + end + + test_sec_t_multiply + local + d: INTEGER_X + g: EC_POINT_F2M + curve: EC_CURVE_F2M + q: EC_POINT_F2M + q_x_solution: INTEGER_X + q_y_solution: INTEGER_X + q_solution: EC_POINT_F2M + correct: BOOLEAN + do + create d.make_from_hex_string ("00000003 A41434AA 99C2EF40 C8495B2E D9739CB2 155A1E0D") + create g.make_sec_t163k1 + create curve.make_sec_t163k1 + create q_x_solution.make_from_hex_string ("00000003 7D529FA3 7E42195F 10111127 FFB2BB38 644806BC") + create q_y_solution.make_from_hex_string ("00000004 47026EEE 8B34157F 3EB51BE5 185D2BE0 249ED776") + create q_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (q_x_solution), create {EC_FIELD_ELEMENT_F2M}.make (q_y_solution)) + q := g.product_value (d, curve) + correct := q ~ q_solution + end + + test1: detachable AES_TEST + test2: detachable CBC_TEST + test3: detachable CFB_TEST + test4: detachable CTR_TEST + test5: detachable DER_TEST + test6: detachable ECB_TEST + test7: detachable EC_TEST + test8: detachable MD5_TEST + test9: detachable OFB_TEST + test10: detachable RSA_TEST + test11: detachable SHA1_TEST + test12: detachable SHA256_TEST + test13: detachable TEST_EC_BINARY + test14: detachable HMAC_SHA256_TEST + +end diff --git a/library/crypto/eel/tests/test.e.orig b/library/crypto/eel/tests/test.e.orig new file mode 100644 index 00000000..1e6a655a --- /dev/null +++ b/library/crypto/eel/tests/test.e.orig @@ -0,0 +1,194 @@ +<<<<<<< local +note + description : "tests application root class" + date : "$Date: 2008-12-29 15:41:59 -0800 (Mon, 29 Dec 2008) $" + revision : "$Revision: 76432 $" + +class + TEST + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + local + key_pair: RSA_KEY_PAIR + message: INTEGER_X + cipher: INTEGER_X + plain: INTEGER_X + signature: INTEGER_X + correct: BOOLEAN + i: INTEGER + do + i := +1 + io.put_string ("Creating keypair%N") + create key_pair.make (1024) + io.put_string ("Created keypair%N") + create message.make_random (128) + cipher := key_pair.public.encrypt (message) + plain := key_pair.private.decrypt (cipher) + io.put_string ("Checked encryption%N") + signature := key_pair.private.sign (message) + correct := key_pair.public.verify (message, signature) + io.put_string ("Checked signing%N") + end + + make_2 + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + i: INTEGER + do + create key.make_sec_t113r1 + create message.make_random_max (key.private.params.n) + from + i := 0 + until + i > 100 + loop + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + i := i + 1 + end + end + + test_sec_t_multiply + local + d: INTEGER_X + g: EC_POINT_F2M + curve: EC_CURVE_F2M + q: EC_POINT_F2M + q_x_solution: INTEGER_X + q_y_solution: INTEGER_X + q_solution: EC_POINT_F2M + correct: BOOLEAN + do + create d.make_from_hex_string ("00000003 A41434AA 99C2EF40 C8495B2E D9739CB2 155A1E0D") + create g.make_sec_t163k1 + create curve.make_sec_t163k1 + create q_x_solution.make_from_hex_string ("00000003 7D529FA3 7E42195F 10111127 FFB2BB38 644806BC") + create q_y_solution.make_from_hex_string ("00000004 47026EEE 8B34157F 3EB51BE5 185D2BE0 249ED776") + create q_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (q_x_solution), create {EC_FIELD_ELEMENT_F2M}.make (q_y_solution)) + q := g.product_value (d, curve) + correct := q ~ q_solution + end + + test1: detachable AES_TEST + test2: detachable CBC_TEST + test3: detachable CFB_TEST + test4: detachable CTR_TEST + test5: detachable DER_TEST + test6: detachable ECB_TEST + test7: detachable EC_TEST + test8: detachable MD5_TEST + test9: detachable OFB_TEST + test10: detachable RSA_TEST + test11: detachable SHA1_TEST + test12: detachable SHA256_TEST + test13: detachable TEST_EC_BINARY + +end +======= +note + description : "tests application root class" + date : "$Date: 2008-12-29 15:41:59 -0800 (Mon, 29 Dec 2008) $" + revision : "$Revision: 76432 $" + +class + TEST + +inherit + ARGUMENTS + +create + make + +feature {NONE} -- Initialization + + make + local + key_pair: RSA_KEY_PAIR + message: INTEGER_X + cipher: INTEGER_X + plain: INTEGER_X + signature: INTEGER_X + correct: BOOLEAN + do + io.put_string ("Creating keypair%N") + create key_pair.make (1024) + io.put_string ("Created keypair%N") + create message.make_random (128) + cipher := key_pair.public.encrypt (message) + plain := key_pair.private.decrypt (cipher) + io.put_string ("Checked encryption%N") + signature := key_pair.private.sign (message) + correct := key_pair.public.verify (message, signature) + io.put_string ("Checked signing%N") + end + + make_2 + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + i: INTEGER + do + create key.make_sec_t113r1 + create message.make_random_max (key.private.params.n) + from + i := 0 + until + i > 100 + loop + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + i := i + 1 + end + end + + test_sec_t_multiply + local + d: INTEGER_X + g: EC_POINT_F2M + curve: EC_CURVE_F2M + q: EC_POINT_F2M + q_x_solution: INTEGER_X + q_y_solution: INTEGER_X + q_solution: EC_POINT_F2M + correct: BOOLEAN + do + create d.make_from_hex_string ("00000003 A41434AA 99C2EF40 C8495B2E D9739CB2 155A1E0D") + create g.make_sec_t163k1 + create curve.make_sec_t163k1 + create q_x_solution.make_from_hex_string ("00000003 7D529FA3 7E42195F 10111127 FFB2BB38 644806BC") + create q_y_solution.make_from_hex_string ("00000004 47026EEE 8B34157F 3EB51BE5 185D2BE0 249ED776") + create q_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (q_x_solution), create {EC_FIELD_ELEMENT_F2M}.make (q_y_solution)) + q := g.product_value (d, curve) + correct := q ~ q_solution + end + + test1: detachable AES_TEST + test2: detachable CBC_TEST + test3: detachable CFB_TEST + test4: detachable CTR_TEST + test5: detachable DER_TEST + test6: detachable ECB_TEST + test7: detachable EC_TEST + test8: detachable MD5_TEST + test9: detachable OFB_TEST + test10: detachable RSA_TEST + test11: detachable SHA1_TEST + test12: detachable SHA256_TEST + test13: detachable TEST_EC_BINARY + test14: detachable HMAC_SHA256_TEST + +end +>>>>>>> other diff --git a/library/crypto/eel/tests/test_ec_binary.e b/library/crypto/eel/tests/test_ec_binary.e new file mode 100644 index 00000000..ece6ef0a --- /dev/null +++ b/library/crypto/eel/tests/test_ec_binary.e @@ -0,0 +1,493 @@ +note + description: "Summary description for {TEST_EC_BINARY}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_EC_BINARY + +inherit + EQA_TEST_SET + +feature -- Binary math + + test_sec_t_multiply + local + d: INTEGER_X + g: EC_POINT_F2M + curve: EC_CURVE_F2M + q: EC_POINT_F2M + q_x_solution: INTEGER_X + q_y_solution: INTEGER_X + q_solution: EC_POINT_F2M + correct: BOOLEAN + do + create d.make_from_hex_string ("00000003 A41434AA 99C2EF40 C8495B2E D9739CB2 155A1E0D") + create g.make_sec_t163k1 + create curve.make_sec_t163k1 + create q_x_solution.make_from_hex_string ("00000003 7D529FA3 7E42195F 10111127 FFB2BB38 644806BC") + create q_y_solution.make_from_hex_string ("00000004 47026EEE 8B34157F 3EB51BE5 185D2BE0 249ED776") + create q_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (q_x_solution), create {EC_FIELD_ELEMENT_F2M}.make (q_y_solution)) + q := g.product_value (d, curve) + correct := q ~ q_solution + assert ("test sec t multiply", correct) + end + + test_sec_t_sign + local + d: INTEGER_X + k: INTEGER_X + e: INTEGER_X + r_x_solution: INTEGER_X + r_y_solution: INTEGER_X + r_solution: EC_POINT_F2M + curve: EC_CURVE_F2M + r: INTEGER_X + s: INTEGER_X + s_solution: INTEGER_X + r_point: EC_POINT_F2M + r_int_solution: INTEGER_X + correct: BOOLEAN + g: EC_POINT_F2M + do + create curve.make_sec_t163k1 + create g.make_sec_t163k1 + create d.make_from_hex_string ("00000003 A41434AA 99C2EF40 C8495B2E D9739CB2 155A1E0D") + create k.make_from_string ("936523985789236956265265265235675811949404040044") + create r_x_solution.make_from_hex_string ("00000004 994D2C41 AA30E529 52B0A94E C6511328 C502DA9B") + create r_y_solution.make_from_hex_string ("00000003 1FC936D7 3163B858 BBC5326D 77C19839 46405264") + create e.make_from_hex_string ("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D") + create r_int_solution.make_from_hex_string ("994D2C41 AA30E529 52AEA846 2370471B 2B0A34AC") + create s_solution.make_from_hex_string ("00000001 52F95CA1 5DA1997A 8C449E00 CD2AA2AC CB988D7F") + create r_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (r_x_solution), create {EC_FIELD_ELEMENT_F2M}.make (r_y_solution)) + r_point := g.product_value (k, curve) + correct := r_point ~ r_solution + assert ("test set t sign 1", correct) + r := r_point.x.x \\ curve.n + correct := r_int_solution ~ r + assert ("test set t sign 2", correct) + s := (k.inverse_value (curve.n) * (r * d + e)) \\ curve.n + correct := s ~ s_solution + assert ("test set t sign 3", correct) + end + + test_sec_t_verify + local + q: EC_POINT_F2M + d: INTEGER_X + curve: EC_CURVE_F2M + e: INTEGER_X + r: INTEGER_X + s: INTEGER_X + u1: INTEGER_X + u2: INTEGER_X + u1_solution: INTEGER_X + u2_solution: INTEGER_X + correct: BOOLEAN + u1g: EC_POINT_F2M + u1g_solution: EC_POINT_F2M + u1g_x: INTEGER_X + u1g_y: INTEGER_X + u2q: EC_POINT_F2M + u2q_solution: EC_POINT_F2M + u2q_x: INTEGER_X + u2q_y: INTEGER_X + r_x: INTEGER_X + r_y: INTEGER_X + r_solution: EC_POINT_F2M + r_point: EC_POINT_F2M + g: EC_POINT_F2M + v: INTEGER_X + do + create curve.make_sec_t163k1 + create d.make_from_hex_string ("00000003 A41434AA 99C2EF40 C8495B2E D9739CB2 155A1E0D") + create r.make_from_hex_string ("994D2C41 AA30E529 52AEA846 2370471B 2B0A34AC") + create s.make_from_hex_string ("00000001 52F95CA1 5DA1997A 8C449E00 CD2AA2AC CB988D7F") + create e.make_from_hex_string ("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D") + create u1_solution.make_from_string ("5658067548292182333034494350975093404971930311298") + create u2_solution.make_from_string ("2390570840421010673757367220187439778211658217319") + create u1g_x.make_from_hex_string ("00000005 1B4B9235 90399545 34D77469 AC7434D7 45BE784D") + create u1g_y.make_from_hex_string ("00000001 C657D070 935987CA 79976B31 6ED2F533 41058956") + create u2q_x.make_from_hex_string ("07FD04AF 05DCAF73 39F6F89C 52EF27FE 94699AED") + create u2q_y.make_from_hex_string ("AA84BE48 C0F1256F A31AAADD F4ADDDD5 AD1F0E14") + create r_x.make_from_hex_string ("00000004 994D2C41 AA30E529 52B0A94E C6511328 C502DA9B") + create r_y.make_from_hex_string ("00000003 1FC936D7 3163B858 BBC5326D 77C19839 46405264") + create u1g_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (u1g_x), create {EC_FIELD_ELEMENT_F2M}.make (u1g_y)) + create u2q_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (u2q_x), create {EC_FIELD_ELEMENT_F2M}.make (u2q_y)) + create r_solution.make_curve_x_y (create {EC_FIELD_ELEMENT_F2M}.make (r_x), create {EC_FIELD_ELEMENT_F2M}.make (r_y)) + create g.make_sec_t163k1 + q := g.product_value (d, curve) + u1 := (e * s.inverse_value (curve.n) \\ curve.n) + u2 := (r * s.inverse_value (curve.n) \\ curve.n) + correct := u1 ~ u1_solution + assert ("test sec t verify 1", correct) + correct := u2 ~ u2_solution + assert ("test sec t verify 2", correct) + u1g := g.product_value (u1, curve) + correct := u1g ~ u1g_solution + assert ("test sec t verify 3", correct) + u2q := q.product_value (u2, curve) + correct := u2q ~ u2q_solution + assert ("test sec t verify 4", correct) + r_point := u1g.plus_value (u2q, curve) + correct := r_point ~ r_solution + v := r_point.x.x \\ curve.n + correct := v ~ r + assert ("test sec t verify 5", correct) + end +feature --Polynomial reflexive tests + test_sec_t113r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t113r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t113r1 reflexive", correct) + end + + test_sec_t113r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t113r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t113r2 reflexive", correct) + end + + test_sec_t131r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t131r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t131r1 reflexive", correct) + end + + test_sec_t131r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t131r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t131r2 reflexive", correct) + end + + test_sec_t163k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t163k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t163k1 reflexive", correct) + end + + test_sec_t163r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t163r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t163r1 reflexive", correct) + end + + test_sec_t163r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t163r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t163r2 reflexive", correct) + end + + test_sec_t193r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t193r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t193r1 reflexive", correct) + end + + test_sec_t193r2_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t193r2 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t193r2 reflexive", correct) + end + + test_sec_t233k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t233k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t233k1 reflexive", correct) + end + + test_sec_t233r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t233r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t233r1 reflexive", correct) + end + + test_sec_t239k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t239k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t239k1 reflexive", correct) + end + + test_sec_t283k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t283k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t283k1 reflexive", correct) + end + + test_sec_t283r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t283r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t283r1 reflexive", correct) + end + + test_sec_t409k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t409k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t409k1 reflexive", correct) + end + + test_sec_t409r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t409r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t409r1 reflexive", correct) + end + + test_sec_t571k1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t571k1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t571k1 reflexive", correct) + end + + test_sec_t571r1_reflexive + local + key: EC_KEY_PAIR + message: INTEGER_X + signature: TUPLE [r: INTEGER_X s: INTEGER_X] + correct: BOOLEAN + do + create key.make_sec_t571r1 + create message.make_random_max (key.private.params.n) + signature := key.private.sign (message) + correct := key.public.verify (message, signature) + assert ("test sec t571r1 reflexive", correct) + end + + test_reduce_1 + local + one: INTEGER_X + a: INTEGER_X + b: INTEGER_X + n: INTEGER_X + curve: EC_CURVE_F2M + element: EC_FIELD_ELEMENT_F2M + expected: INTEGER_X + do + create expected.make_from_hex_string ("13b6c2e54bb8c935c13fab54639da") + create one.make_from_hex_string ("54505401551104100555400451414110050100000151441011150550") + create a.make_from_hex_string ("3088250ca6e7c7fe649ce85820f7") + create b.make_from_hex_string ("e8bee4d3e2260744188be0e9c723") + create n.make_from_hex_string ("100000000000000d9ccec8a39e56f") + create curve.make (0x71, 9, 0, 0, a, b, n) + create element.make (one) + element.reduce (one, curve) + assert ("test reduce 1", one ~ expected) + end + + test_square_1 + local + one: INTEGER_X + a: INTEGER_X + b: INTEGER_X + n: INTEGER_X + curve: EC_CURVE_F2M + element: EC_FIELD_ELEMENT_F2M + expected: INTEGER_X + do + create one.make_from_hex_string ("ece1f5243f82d99431001da4573c") + create expected.make_from_hex_string ("13b6c2e54bb8c935c13fab54639da") + create a.make_from_hex_string ("3088250ca6e7c7fe649ce85820f7") + create b.make_from_hex_string ("e8bee4d3e2260744188be0e9c723") + create n.make_from_hex_string ("100000000000000d9ccec8a39e56f") + create curve.make (0x71, 9, 0, 0, a, b, n) + create element.make (one) + element.square (curve) + assert ("test square 1", element.x ~ expected) + end + + test_square_2 + local + parameters: EC_DOMAIN_PARAMETERS_F2M + one: INTEGER_X + element: EC_FIELD_ELEMENT_F2M + expected: INTEGER_X + do + create one.make_from_hex_string ("3 ffffffff ffffffff ffffffff ffffffff") + create expected.make_from_hex_string ("aaaaaaaaaaaaaaaaaaaaaaaaaaaabfee") + create parameters.make_sec_t131r1 + create element.make (one) + element.square (parameters.curve) + assert ("test square 2", element.x ~ expected) + end + + test_square_3 + local + parameters: EC_DOMAIN_PARAMETERS_F2M + one: INTEGER_X + element: EC_FIELD_ELEMENT_F2M + expected: INTEGER_X + do + create parameters.make_sec_t131r1 + create one.make_from_hex_string ("b11acac3b1c28415a4e733010375a5b8") + create expected.make_from_hex_string ("18b11dd51ffe1f2aeef0ec79fae0b67f7") + create element.make (one) + element.square (parameters.curve) + assert ("test square 3", element.x ~ expected) + end + + test_product_1 + local + curve: EC_CURVE_F2M + one: EC_POINT_F2M + expected: EC_POINT_F2M + multiplicand: INTEGER_X + do + create one.make_curve_x_y (create {INTEGER_X}.make_from_hex_string ("9d73616f35f4ab1407d73562c10f"), create {INTEGER_X}.make_from_hex_string ("a52830277958ee84d1315ed31886")) + create expected.make_curve_x_y (create {INTEGER_X}.make_from_hex_string ("1a42d8acf7568670dfd067fde38ff"), create {INTEGER_X}.make_from_hex_string ("11747870124d247a94b527a2fbc2e")) + create multiplicand.make_from_hex_string ("a077518c809013ae8ec6baecd515") + create curve.make (0x71, 9, 0, 0, create {INTEGER_X}.make_from_hex_string ("3088250ca6e7c7fe649ce85820f7"), create {INTEGER_X}.make_from_hex_string ("e8bee4d3e2260744188be0e9c723"), create {INTEGER_X}.make_from_hex_string ("100000000000000d9ccec8a39e56f")) + one.product (multiplicand, curve) + assert ("test product 1", one ~ expected) + end + + test_product_2 + local + curve: EC_CURVE_F2M + one: EC_FIELD_ELEMENT_F2M + expected: EC_FIELD_ELEMENT_F2M + multiplicand: INTEGER_X + do + create one.make (create {INTEGER_X}.make_from_hex_string ("a52830277958ee84d1315ed31886")) + create multiplicand.make_from_hex_string ("fa499cd55090de5385193e34792c") + create expected.make (create {INTEGER_X}.make_from_hex_string ("7192944b0a76728036d728c69633")) + create curve.make (0x71, 9, 0, 0, create {INTEGER_X}.make_from_hex_string ("3088250ca6e7c7fe649ce85820f7"), create {INTEGER_X}.make_from_hex_string ("e8bee4d3e2260744188be0e9c723"), create {INTEGER_X}.make_from_hex_string ("100000000000000d9ccec8a39e56f")) + one.product (multiplicand, curve) + assert ("test product 2", one ~ expected) + end +end diff --git a/library/crypto/eel/tests/test_ec_field_element_f2m.e b/library/crypto/eel/tests/test_ec_field_element_f2m.e new file mode 100644 index 00000000..8102590a --- /dev/null +++ b/library/crypto/eel/tests/test_ec_field_element_f2m.e @@ -0,0 +1,14 @@ +note + description: "Summary description for {TEST_EC_FIELD_ELEMENT_F2M}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + TEST_EC_FIELD_ELEMENT_F2M + +inherit + EQA_TEST_SET + +feature +end diff --git a/library/crypto/eel/tests/tests-safe.ecf b/library/crypto/eel/tests/tests-safe.ecf new file mode 100644 index 00000000..eefb141a --- /dev/null +++ b/library/crypto/eel/tests/tests-safe.ecf @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + /.hg$ + /EIFGENs$ + /CVS$ + /.svn$ + + + + diff --git a/library/crypto/eel/tests/tests.ecf b/library/crypto/eel/tests/tests.ecf new file mode 100644 index 00000000..5a7254f4 --- /dev/null +++ b/library/crypto/eel/tests/tests.ecf @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + /.svn$ + /EIFGENs$ + /CVS$ + /.hg$ + + + + diff --git a/library/crypto/eel/tests/tests.rc b/library/crypto/eel/tests/tests.rc new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/library/crypto/eel/tests/tests.rc @@ -0,0 +1 @@ + diff --git a/library/crypto/eel/x509/algorithm_identifier.e b/library/crypto/eel/x509/algorithm_identifier.e new file mode 100644 index 00000000..1fb9c4dc --- /dev/null +++ b/library/crypto/eel/x509/algorithm_identifier.e @@ -0,0 +1,38 @@ +note + description: "x509v3 AlgorithmIdentifier sequence" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "When you subsidize poverty and failure, you get more of both. - James Dale Davidson, National Taxpayers Union" + +class + ALGORITHM_IDENTIFIER + +inherit + ANY + redefine + is_equal + end + +create + make + +feature + make (algorithm_a: OBJECT_IDENTIFIER parameters_a: ALGORITHM_PARAMETERS) + do + algorithm := algorithm_a + parameters := parameters_a + end + + is_equal (other: like Current): BOOLEAN + do + result := algorithm ~ other.algorithm and parameters ~ other.parameters + ensure then + algorithm ~ other.algorithm + parameters ~ other.parameters + end + +feature + algorithm: OBJECT_IDENTIFIER + parameters: ALGORITHM_PARAMETERS +end diff --git a/library/crypto/eel/x509/algorithm_parameters.e b/library/crypto/eel/x509/algorithm_parameters.e new file mode 100644 index 00000000..043b848a --- /dev/null +++ b/library/crypto/eel/x509/algorithm_parameters.e @@ -0,0 +1,11 @@ +note + description: "Summary description for {ALGORITHM_PARAMETERS}." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "If we have to kill 12 people to save 1 human life it will have been worth it. - Unknown" + +class + ALGORITHM_PARAMETERS + +end diff --git a/library/crypto/eel/x509/attribute_type_and_value.e b/library/crypto/eel/x509/attribute_type_and_value.e new file mode 100644 index 00000000..a69e2349 --- /dev/null +++ b/library/crypto/eel/x509/attribute_type_and_value.e @@ -0,0 +1,24 @@ +note + description: "x509v3 AttributeTypeAndValue sequence" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Truth and news are not the same thing. - Katharine Graham, owner of The Washington Post" + +class + ATTRIBUTE_TYPE_AND_VALUE + +create + make + +feature + make (type_a: OBJECT_IDENTIFIER value_a: SPECIAL [NATURAL_8]) + do + type := type_a + value := value_a + end + +feature + type: OBJECT_IDENTIFIER + value: SPECIAL [NATURAL_8] +end diff --git a/library/crypto/eel/x509/certificate.e b/library/crypto/eel/x509/certificate.e new file mode 100644 index 00000000..3b7f28e0 --- /dev/null +++ b/library/crypto/eel/x509/certificate.e @@ -0,0 +1,29 @@ +note + description: "x509v3 Certificate sequence." + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Everyone thinks about changing the world, but no one thinks about changing himself. - Leo Tolstoy" + +class + CERTIFICATE + +create + make + +feature + make (tbs_certificate_a: TBS_CERTIFICATE signature_algorithm_a: ALGORITHM_IDENTIFIER signature_value_a: SPECIAL [NATURAL_8]) + do + tbs_certificate := tbs_certificate_a + signature_algorithm := signature_algorithm_a + signature_value := signature_value_a + end + +feature + tbs_certificate: TBS_CERTIFICATE + signature_algorithm: ALGORITHM_IDENTIFIER + signature_value: SPECIAL [NATURAL_8] + +invariant + mismatched_algorithms: signature_algorithm ~ tbs_certificate.signature +end diff --git a/library/crypto/eel/x509/extension.e b/library/crypto/eel/x509/extension.e new file mode 100644 index 00000000..52fd2b97 --- /dev/null +++ b/library/crypto/eel/x509/extension.e @@ -0,0 +1,26 @@ +note + description: "x509v3 extension sequence" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "The Constitution is not an instrument for the government to restrain the people, it is an instrument for the people to restrain the government - lest it come to dominate our lives and interests. - Patrick Henry" + +class + EXTENSION + +create + make + +feature + make (extn_id_a: OBJECT_IDENTIFIER critical_a: BOOLEAN extn_value_a: SPECIAL [NATURAL_8]) + do + extn_id := extn_id_a + critical := critical_a + extn_value := extn_value_a + end + +feature + extn_id: OBJECT_IDENTIFIER + critical: BOOLEAN + extn_value: SPECIAL [NATURAL_8] +end diff --git a/library/crypto/eel/x509/name.e b/library/crypto/eel/x509/name.e new file mode 100644 index 00000000..e7193daf --- /dev/null +++ b/library/crypto/eel/x509/name.e @@ -0,0 +1,22 @@ +note + description: "x509v3 Name choice" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "When goods don't cross borders, soldiers will. - Fredric Bastiat, early French economists" + +class + NAME + +create + make + +feature + make (rdn_sequence_a: LIST [ATTRIBUTE_TYPE_AND_VALUE]) + do + rdn_sequence := rdn_sequence_a + end + +feature + rdn_sequence: LIST [ATTRIBUTE_TYPE_AND_VALUE] +end diff --git a/library/crypto/eel/x509/object_identifier.e b/library/crypto/eel/x509/object_identifier.e new file mode 100644 index 00000000..e72e7d04 --- /dev/null +++ b/library/crypto/eel/x509/object_identifier.e @@ -0,0 +1,108 @@ +note + description: "ASN.1 OIDs" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: + "[ + Virtually all reasonable laws are obeyed, not because they are the law, but because reasonable people would do that anyway. + If you obey a law simply because it is the law, that's a pretty likely sign that it shouldn't be a law. - Unknown + ]" + +class + OBJECT_IDENTIFIER + +inherit + ANY + redefine + is_equal + end + +create + make_md2, + make_md5, + make_id_sha1, + make_md2_with_rsa_encryption, + make_md5_with_rsa_encryption, + make_sha_1_with_rsa_encryption, + make_id_dsa_with_sha1, + make_ecdsa_with_sha1, + make_pkcs_1 + +feature + make_md2 + do + id := "1.2.840.113549.2.2" + end + + make_md5 + do + id := "1.2.840.113549.2.5" + end + + make_id_sha1 + do + id := "1.3.14.3.2.26" + end + + make_md2_with_rsa_encryption + do + id := "1.2.840.113549.1.1.2" + end + + make_md5_with_rsa_encryption + do + id := "1.2.840.113549.1.1.4" + end + + make_sha_1_with_rsa_encryption + do + id := "1.2.840.113549.1.1.5" + end + + make_id_dsa_with_sha1 + do + id := "1.2.840.10040.4.3" + end + + make_ecdsa_with_sha1 + do + id := "1.2.840.10045.4.1" + end + + make_pkcs_1 + do + id := "1.2.840.113549.1" + end + + make_sha_224_with_rsa_encryption + do + id := "1.2.840.113549.1.14" + end + + make_sha_256_with_rsa_encryption + do + id := "1.2.840.113549.1.11" + end + + make_sha_384_with_rsa_encryption + do + id := "1.2.840.113549.1.12" + end + + make_sha_512_with_rsa_encryption + do + id := "1.2.840.113549.1.13" + end + +feature + is_equal (other: like Current): BOOLEAN + do + result := id ~ other.id + ensure then + id ~ other.id + end + +feature + id: STRING +end diff --git a/library/crypto/eel/x509/subject_public_key_info.e b/library/crypto/eel/x509/subject_public_key_info.e new file mode 100644 index 00000000..fcec7aa6 --- /dev/null +++ b/library/crypto/eel/x509/subject_public_key_info.e @@ -0,0 +1,24 @@ +note + description: "x509v3 SubjectPublicKeyInfo sequence" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "One of the penalties for refusing to participate in politics is that you end up being governed by your inferiors. - Plato" + +class + SUBJECT_PUBLIC_KEY_INFO + +create + make + +feature + make (algorithm_a: STRING subject_public_key_a: STRING) + do + algorithm := algorithm_a + subject_public_key := subject_public_key_a + end + +feature + algorithm: STRING + subject_public_key: STRING +end diff --git a/library/crypto/eel/x509/tbs_certificate.e b/library/crypto/eel/x509/tbs_certificate.e new file mode 100644 index 00000000..da1aa546 --- /dev/null +++ b/library/crypto/eel/x509/tbs_certificate.e @@ -0,0 +1,72 @@ +note + description: "x509v3 TBSCertificate sequence" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "Democracy is a pathetic belief in the collective wisdom of individual ignorance. - H.L. Mencken" + +class + TBS_CERTIFICATE + +inherit + DER_ENCODABLE + +create + make + +feature + make ( version_a: INTEGER_32 serial_number_a: INTEGER_X signature_a: ALGORITHM_IDENTIFIER issuer_a: NAME validity_a: VALIDITY + subject_a: NAME subject_public_key_info_a: SUBJECT_PUBLIC_KEY_INFO issuer_unique_id_a: SPECIAL [NATURAL_8] + subject_unique_id_a: SPECIAL [NATURAL_8] extensions_a: LIST [EXTENSION]) + require + + do + version := version_a + serial_number := serial_number_a + signature := signature_a + issuer := issuer_a + validity := validity_a + subject := subject_a + subject_public_key_info := subject_public_key_info_a + issuer_unique_id := issuer_unique_id_a + subject_unique_id := subject_unique_id_a + extensions := extensions_a + end + +feature + der_encode (target: DER_OCTET_SINK) + do + + end + +feature + version: INTEGER_32 + serial_number: INTEGER_X + signature: ALGORITHM_IDENTIFIER + issuer: NAME + validity: VALIDITY + subject: NAME + subject_public_key_info: SUBJECT_PUBLIC_KEY_INFO + issuer_unique_id: SPECIAL [NATURAL_8] + subject_unique_id: SPECIAL [NATURAL_8] + extensions: LIST [EXTENSION] + +feature + valid_version (in: INTEGER_32): BOOLEAN + do + result := in = 2 + ensure + result = (in = 2) + end + + valid_serial_number (in: INTEGER_X): BOOLEAN + do + result := (in >= in.one) and in.bits <= 20 * 8 + ensure + result = ((in >= in.one) and in.bits <= 20 * 8) + end + +invariant + valid_version (version) + valid_serial_number (serial_number) +end diff --git a/library/crypto/eel/x509/validity.e b/library/crypto/eel/x509/validity.e new file mode 100644 index 00000000..3d875460 --- /dev/null +++ b/library/crypto/eel/x509/validity.e @@ -0,0 +1,24 @@ +note + description: "x509v3 Validity sequence" + author: "Colin LeMahieu" + date: "$Date$" + revision: "$Revision$" + quote: "If we don't believe in freedom of expression for people we despise, we don't believe in it at all. - Noam Chomsky" + +class + VALIDITY + +create + make + +feature + make (not_before_a: TIME not_after_a: TIME) + do + not_before := not_before_a + not_after := not_after_a + end + +feature + not_before: TIME + not_after: TIME +end