Compare commits

..

6 Commits

Author SHA1 Message Date
Jocelyn Fiat
f898df0ffa Merge branch 'master' of https://github.com/EiffelWebFramework/EWF.wiki into release-0.1
Conflicts:
	doc/wiki/Home.md
2012-06-29 07:41:58 +02:00
Jocelyn Fiat
0375072540 updated git howto 2012-06-27 09:37:29 +02:00
Jocelyn Fiat
ad3b975d0a use svn export instead of svn checkout 2012-06-27 09:31:43 +02:00
Jocelyn Fiat
37e60a1f92 If library/cURL exists, do not copy cURL to contrib/library/network/cURL 2012-06-26 22:50:36 +02:00
Jocelyn Fiat
c7db4529a3 When installing, remove the folder "fonts" from the nino's example 2012-06-20 10:42:03 +02:00
Jocelyn Fiat
7273f5086d release v0.1 2012-06-20 10:16:11 +02:00
637 changed files with 40476 additions and 23358 deletions

View File

@@ -1,6 +1,6 @@
# Eiffel Web Framework
* version: v0.2
## Version: v0.1
## Overview
@@ -17,19 +17,25 @@ For download, check
* https://github.com/EiffelWebFramework/EWF/downloads
## Requirements
* Compiling from EiffelStudio 7.0
* Developped using EiffelStudio 7.1 and 7.2 (on Windows, Linux)
* Tested using EiffelStudio 7.1 with "jenkins" CI server (not compatible with 6.8 due to use of `TABLE_ITERABLE')
* Developped using EiffelStudio 7.0 (on Windows, Linux)
* Tested using EiffelStudio 7.0 with "jenkins" CI server (and v6.8 for time to time)
* The code have to allow __void-safe__ compilation and non void-safe system (see [more about void-safety](http://docs.eiffel.com/book/method/void-safe-programming-eiffel) )
## How to get the source code?
* git clone https://github.com/EiffelWebFramework/EWF.git
* svn checkout https://github.com/EiffelWebFramework/EWF/trunk
Using git version >= 1.6.5
* git clone --recursive https://github.com/EiffelWebFramework/EWF.git
* Notes:
** It does not use submodule anymore due to recurrent trouble for users.
** EWF is also provided by delivery of EiffelStudio (starting from version 7.1 shipping v0.1, and 7.2 that ships v0.2)
Otherwise, try
* git clone https://github.com/EiffelWebFramework/EWF.git
* cd Eiffel-Web-Framework
* git submodule update --init
* git submodule foreach --recursive git checkout master
An alternative to the last 2 instructions is to use the script from tools folder:
* cd tools
* update_git_working_copy
* And to build the required and related Clibs
* cd contrib/ise_library/cURL
@@ -42,12 +48,12 @@ For download, check
* connectors: various web server connectors for EWSGI
* libfcgi: Wrapper for libfcgi SDK
* __wsf__: Web Server Framework [read more](library/server/wsf)
* __router__: URL dispatching/routing based on uri, uri_template, or custom [read more](library/server/wsf/router)
* include URL dispatching/routing based on uri, uri_template, or custom [read more](library/server/wsf/router)
### protocol
* __http__: HTTP related classes, constants for status code, content types, ... [read more](library/protocol/http)
* __uri_template__: URI Template library (parsing and expander) [read more](library/protocol/uri_template)
*not yet released: __CONNEG__: CONNEG library (Content-type Negociation) [read more](library/protocol/CONNEG)
* __CONNEG__: CONNEG library (Content-type Negociation) [read more](library/protocol/CONNEG)
### client
* __http_client__: simple HTTP client based on cURL [read more](library/client/http_client)
@@ -55,18 +61,20 @@ For download, check
### text
* __encoder__: Various simpler encoders: base64, url-encoder, xml entities, html entities [read more](library/text/encoder)
### crypto
* eel
* eapml
### Others
* error: very simple/basic library to handle error
## External libraries under 'contrib'
* [Eiffel Web Nino](contrib/library/server/nino)
* ..
* contrib/ise_library/cURL
* contrib/ise_library/math/eapml
* contrib/ise_library/text/encryption/eel
* contrib/library/text/parser/json
## Draft folder = call for contribution ##
### library/server/request ###
* request
* rest: (experimental) "a" RESTful library to help building RESTful services
## Examples
..

1
VERSION.txt Normal file
View File

@@ -0,0 +1 @@
Version v0.1

View File

@@ -0,0 +1,4 @@
Eiffel Arbitrary Precision Mathematics Library
Contribution from Colin LeMahieu
see original source: https://github.com/clemahieu/eapml

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-6-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-6-0 http://www.eiffel.com/developers/xml/configuration-1-6-0.xsd" name="eapml" uuid="3E9258E1-383A-40BF-864B-231FC8F25ADF" library_target="eapml">
<description>Eiffel Arbitrary Precision Mathematics Library
Note: you should set 'eapml_scan_type' to 'gcc' or 'vc'
and 'eapml_limb_type' to 'natural_32' (or 'natural_64')
If not, default values will be used depending on the platform
</description>
<target name="eapml">
<file_rule>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.hg$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<description>Eiffel Arbitrary Precision Mathematics</description>
<root all_classes="true"/>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<cluster name="bit_scan_gcc" location=".\src\bit_scan_gcc\" recursive="true">
<condition>
<custom name="eapml_scan_type" value="gcc"/>
</condition>
<condition>
<platform excluded_value="windows"/>
<custom name="eapml_scan_type" excluded_value="vc"/>
</condition>
</cluster>
<cluster name="bit_scan_vc" location=".\src\bit_scan_vc\" recursive="true">
<condition>
<custom name="eapml_scan_type" value="vc"/>
</condition>
<condition>
<platform value="windows"/>
<custom name="eapml_scan_type" excluded_value="gcc"/>
</condition>
</cluster>
<cluster name="eapml" location=".\src\" recursive="true">
<file_rule>
<exclude>/bit_scan_vc$</exclude>
<exclude>/bit_scan_gcc$</exclude>
<exclude>/limb_natural_32$</exclude>
<exclude>/limb_natural_64$</exclude>
</file_rule>
<file_rule>
<exclude>^/mp/number/support$</exclude>
</file_rule>
</cluster>
<cluster name="limb_natural_32" location=".\src\limb_natural_32\" recursive="true">
<!--
<condition>
<custom name="eapml_limb_type" value="natural_32"/>
</condition>
-->
</cluster>
<!--
<cluster name="limb_natural_64" location=".\src\limb_natural_64\" recursive="true">
<condition>
<custom name="eapml_limb_type" value="natural_64"/>
</condition>
</cluster>
-->
</target>
</system>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="eapml" uuid="3E9258E1-383A-40BF-864B-231FC8F25ADF" library_target="eapml">
<description>Eiffel Arbitrary Precision Mathematics Library
Note: you should set 'eapml_scan_type' to 'gcc' or 'vc'
and 'eapml_limb_type' to 'natural_32' (or 'natural_64')
If not, default values will be used depending on the platform
</description>
<target name="eapml">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/\.svn$</exclude>
<exclude>/\.hg$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="false" void_safety="none" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<cluster name="bit_scan_gcc" location=".\src\bit_scan_gcc\" recursive="true">
<condition>
<custom name="eapml_scan_type" value="gcc"/>
</condition>
<condition>
<platform excluded_value="windows"/>
<custom name="eapml_scan_type" excluded_value="vc"/>
</condition>
</cluster>
<cluster name="bit_scan_vc" location=".\src\bit_scan_vc\" recursive="true">
<condition>
<custom name="eapml_scan_type" value="vc"/>
</condition>
<condition>
<platform value="windows"/>
<custom name="eapml_scan_type" excluded_value="gcc"/>
</condition>
</cluster>
<cluster name="eapml" location=".\src\" recursive="true">
<file_rule>
<exclude>/bit_scan_vc$</exclude>
<exclude>/bit_scan_gcc$</exclude>
<exclude>/limb_natural_32$</exclude>
<exclude>/limb_natural_64$</exclude>
</file_rule>
<file_rule>
<exclude>^/mp/number/support$</exclude>
</file_rule>
</cluster>
<cluster name="limb_natural_32" location=".\src\limb_natural_32\" recursive="true">
<!--
<condition>
<custom name="eapml_limb_type" value="natural_32"/>
</condition>
-->
</cluster>
<!--
<cluster name="limb_natural_64" location=".\src\limb_natural_64\" recursive="true">
<condition>
<custom name="eapml_limb_type" value="natural_64"/>
</condition>
</cluster>
-->
</target>
</system>

View File

@@ -0,0 +1,59 @@
note
description: "Summary description for {LIMB_BIT_SCANNING}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,59 @@
note
description: "Summary description for {LIMB_BIT_SCANNING}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,19 @@
note
description: "An exception when dividing by zero"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,224 @@
note
description: "Convert between character codes and numbers ignoring case"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,276 @@
note
description: "Convert between character codes and numbers case-sensitive"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,20 @@
note
description: "A strategy for converting character codes to numbers and vica-versa"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,77 @@
note
description: "Summary description for {INTEGER_X_ACCESS}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,914 @@
note
description: "Summary description for {INTEGER_X_ARITHMETIC}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,155 @@
note
description: "Summary description for {INTEGER_X_ASSIGNMENT}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,200 @@
note
description: "Summary description for {INTEGER_X_COMPARISON}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,429 @@
note
description: "Summary description for {INTEGER_X_DIVISION}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,11 @@
note
description: "Summary description for {INTEGER_X_FACILITIES}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,145 @@
note
description: "Summary description for {INTEGER_X_GCD}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,335 @@
note
description: "Summary description for {INTEGER_X_IO}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,967 @@
note
description: "Summary description for {INTEGER_X_NUMBER_THEORY}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,108 @@
note
description: "Summary description for {INTEGER_X_RANDOM}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,49 @@
note
description: "Summary description for {INTEGER_X_SIZING}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
note
description: "Summary description for {POWERS}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,44 @@
note
description: "Summary description for {RAND_LC_STRUCT}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,262 @@
note
description: "Summary description for {NUMBER_ACCESS}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
note
description: "Summary description for {NUMBER_ASSIGNMENT}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,39 @@
note
description: "Summary description for {NUMBER_COMPARISON}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,332 @@
note
description: "Summary description for {NUMBER_LOGIC}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,849 @@
note
description: "Summary description for {NUMBER_NUMBER_THEORETIC}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,52 @@
note
description: "Summary description for {NUMBER_SIZING}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,37 @@
note
description: "Summary description for {NUMBER_UTILITY}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,66 @@
note
description: "An INTEGER_X whos value cannot change"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,89 @@
note
description: "An arbitrary precision integer"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -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: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,19 @@
note
description: "An exception when an {INTEGER_X} doesn't have a modular inverse"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,17 @@
note
description: "Summary description for {LIMB_DEFINITION}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,458 @@
note
description: "Summary description for {LIMB_MANIPULATION}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,249 @@
note
description: "A Linear congruential random number generator"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
note
description: "Summary description for {RANDSTRUCT}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -0,0 +1,43 @@
note
description : "Library unit test root class"
date : "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision : "$Revision: 87787 $"
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

View File

@@ -0,0 +1,19 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
testing: "type/manual"
class
TEST_INTEGER_FUNCTIONS
inherit
EQA_TEST_SET
feature -- Test routines
end

View File

@@ -0,0 +1,557 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,395 @@
note
description: "Summary description for {TEST_INTEGER_X_ACCESS}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,208 @@
note
description: "Summary description for {TEST_INTEGER_ARITHMETIC}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,217 @@
note
description: "Summary description for {TEST_INTEGER_X_ASSIGNMENT}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,32 @@
note
description: "Summary description for {INTEGER_X_DIVISION}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,92 @@
note
description: "Summary description for {TEST_INTEGER_X_GCD}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,89 @@
note
description: "Summary description for {TEST_INTEGER_X_IO}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,126 @@
note
description: "Summary description for {TEST_INTEGER_X_LOGIC}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,266 @@
note
description: "Summary description for {TEST_INTEGER_X_NUMBER_THEORY}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,82 @@
note
description: "Summary description for {TEST_INTEGER_X_RANDOM}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,37 @@
note
description: "Summary description for {TEST_LIMB_MANIPULATION}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,85 @@
note
description: "Summary description for {TEST_RANDSTRUCT_LC}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,46 @@
note
description: "Summary description for {TEST_RANDSTRUCT_MT}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,463 @@
note
description: "Summary description for {TEST_NUMBER_ARITHMETIC}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,458 @@
note
description: "Summary description for {TEST_NUMBER_DIVISION}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,446 @@
note
description: "Summary description for {TEST_NUMBER_GCD}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,252 @@
note
description: "Summary description for {TEST_NUMBER_LOGIC}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,146 @@
note
description: "Summary description for {TEST_NUMBER_NUMBER_THEORETIC}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-5-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-5-0 http://www.eiffel.com/developers/xml/configuration-1-5-0.xsd" name="tests" uuid="9FA1C743-D3D3-4ABA-BAB8-27986A422F01">
<target name="tests">
<root class="TEST" feature="make"/>
<option trace="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<variable name="eapml_limb_type" value="natural_32"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="eapml" location="..\eapml-safe.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<cluster name="tests" location=".\" recursive="true">
<file_rule>
<exclude>/.svn$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.hg$</exclude>
</file_rule>
<visible class="TEST" feature="make_2"/>
</cluster>
</target>
<target name="tests_dotnet" extends="tests">
<setting name="msil_generation" value="true"/>
</target>
</system>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-5-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-5-0 http://www.eiffel.com/developers/xml/configuration-1-5-0.xsd" name="tests" uuid="9FA1C743-D3D3-4ABA-BAB8-27986A422F01">
<target name="tests" abstract="true">
<root class="TEST" feature="make"/>
<option trace="false" warning="true" full_class_checking="true" is_attached_by_default="false" void_safety="none" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="eapml" location="..\eapml.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
<cluster name="tests" location=".\" recursive="true">
<file_rule>
<exclude>/.hg$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<visible class="TEST" feature="make_2"/>
</cluster>
</target>
<target name="tests_gcc_32" extends="tests">
<variable name="eapml_limb_type" value="natural_32"/>
<variable name="eapml_scan_type" value="gcc"/>
</target>
<target name="tests_vc_32" extends="tests">
<variable name="eapml_limb_type" value="natural_32"/>
<variable name="eapml_scan_type" value="vc"/>
</target>
</system>

View File

@@ -0,0 +1,4 @@
An encryption library in Eiffel
Contribution from Colin LeMahieu
see original source: https://github.com/clemahieu/eel

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-6-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-6-0 http://www.eiffel.com/developers/xml/configuration-1-6-0.xsd" name="eel" uuid="2A5F116C-6A76-4AB7-81A0-A73DF516F4F3" library_target="eel">
<target name="eel">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
<exclude>/.hg$</exclude>
</file_rule>
<root all_classes="true"/>
<option profile="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="eapml" location="..\..\..\math\eapml\eapml-safe.ecf"/>
<cluster name="eel" location=".\src" recursive="true">
<option syntax="standard">
<assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
</option>
<file_rule>
<exclude>/x509$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-6-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-5-0 http://www.eiffel.com/developers/xml/configuration-1-5-0.xsd" name="eel" uuid="2A5F116C-6A76-4AB7-81A0-A73DF516F4F3" library_target="eel">
<target name="eel">
<file_rule>
<exclude>/\.svn$</exclude>
<exclude>/\.hg$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<root all_classes="true"/>
<option profile="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="none" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="eapml" location="..\..\..\math\eapml\eapml.ecf"/>
<cluster name="eel" location=".\src" recursive="true">
<option syntax="standard">
<assertions precondition="true" postcondition="true" check="true" loop="true" supplier_precondition="true"/>
</option>
<file_rule>
<exclude>/x509$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -0,0 +1,62 @@
note
description: "Summary description for {RSA_KEY_PAIR}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,46 @@
note
description: "Summary description for {RSA_PRIVATE_KEY}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,43 @@
note
description: "Summary description for {RSA_KEY}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,150 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,531 @@
note
description: "Tagging class for various size/speed tradeoffs of AES"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,758 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,148 @@
note
description: "Summary description for {ARRAY_FACILITIES}."
author: "Colin LeMahieu"
date: "$Date: 2012-01-17 09:03:25 +0100 (mar., 17 janv. 2012) $"
revision: "$Revision: 88192 $"
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_64 |<< 56
Result := Result | (source [offset + 1].to_natural_64 |<< 48)
Result := Result | (source [offset + 2].to_natural_64 |<< 40)
Result := Result | (source [offset + 3].to_natural_64 |<< 32)
Result := Result | (source [offset + 4].to_natural_64 |<< 24)
Result := Result | (source [offset + 5].to_natural_64 |<< 16)
Result := Result | (source [offset + 6].to_natural_64 |<< 8)
Result := Result | source [offset + 7].to_natural_64
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

View File

@@ -0,0 +1,56 @@
note
description: "Facilities to use a stream of bytes as blocks of bytes"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,19 @@
note
description: "Summary description for {BYTE_64_BIT_BLOCK_FACILITIES}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,85 @@
note
description: "Summary description for {ARRAY_FACILITIES}."
author: "Colin LeMahieu"
date: "$Date: 2012-05-24 12:02:28 +0200 (jeu., 24 mai 2012) $"
revision: "$Revision: 88775 $"
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 + 1
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

View File

@@ -0,0 +1,36 @@
note
description: "Facilities for INTEGER_X constants"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,29 @@
note
description: "Summary description for {ARRAY_DER_SINK}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,44 @@
note
description: "Summary description for {ARRAY_DER_SOURCE}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,18 @@
note
description: "An object that is DER encodable"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,24 @@
note
description: "Summary description for {DER_ENCODING}."
author: ""
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
class
DER_ENCODING
inherit
DEVELOPER_EXCEPTION
create
make
feature
make (reason_a: STRING)
do
reason := reason_a
end
feature
reason: STRING
end

View File

@@ -0,0 +1,196 @@
note
description: "Summary description for {DER_FACILITIES}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,15 @@
note
description: "A sink for DER octets"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,27 @@
note
description: "DER octet source"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,31 @@
note
description: "ASN.1 universal class tag assignments X.680 8.4"
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,283 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,346 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,363 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,118 @@
note
description: "Summary description for {SHA_FUNCTIONS}."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -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

View File

@@ -0,0 +1,14 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,23 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,419 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

View File

@@ -0,0 +1,230 @@
note
description: "Objects that ..."
author: "Colin LeMahieu"
date: "$Date: 2011-11-11 18:13:16 +0100 (ven., 11 nov. 2011) $"
revision: "$Revision: 87787 $"
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

Some files were not shown because too many files have changed in this diff Show More