rocket-js 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. data/.gitignore +0 -11
  2. data/Rakefile +33 -47
  3. data/lib/rocket/js.rb +0 -2
  4. data/lib/rocket/js/builder.rb +2 -2
  5. data/lib/rocket/js/cli.rb +1 -1
  6. data/rocket-js.gemspec +23 -80
  7. data/src/vendor/web-socket-js/FABridge.js +604 -0
  8. data/src/vendor/web-socket-js/README.txt +109 -0
  9. data/src/vendor/web-socket-js/WebSocketMain.swf +0 -0
  10. data/src/vendor/web-socket-js/WebSocketMainInsecure.zip +0 -0
  11. data/src/vendor/web-socket-js/flash-src/WebSocket.as +473 -0
  12. data/src/vendor/web-socket-js/flash-src/WebSocketMain.as +88 -0
  13. data/src/vendor/web-socket-js/flash-src/WebSocketMainInsecure.as +19 -0
  14. data/src/vendor/web-socket-js/flash-src/WebSocketStateEvent.as +32 -0
  15. data/src/vendor/web-socket-js/flash-src/bridge/FABridge.as +943 -0
  16. data/src/vendor/web-socket-js/flash-src/build.sh +10 -0
  17. data/src/vendor/web-socket-js/flash-src/com/adobe/net/proxies/RFC2817Socket.as +204 -0
  18. data/src/vendor/web-socket-js/flash-src/com/gsolo/encryption/MD5.as +375 -0
  19. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/Crypto.as +287 -0
  20. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/MozillaRootCertificates.as +3235 -0
  21. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509Certificate.as +218 -0
  22. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509CertificateCollection.as +57 -0
  23. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/HMAC.as +82 -0
  24. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHMAC.as +27 -0
  25. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHash.as +21 -0
  26. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MAC.as +137 -0
  27. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD2.as +124 -0
  28. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD5.as +204 -0
  29. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA1.as +106 -0
  30. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA224.as +28 -0
  31. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA256.as +115 -0
  32. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHABase.as +71 -0
  33. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/ARC4.as +90 -0
  34. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/IPRNG.as +20 -0
  35. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/Random.as +119 -0
  36. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/TLSPRF.as +142 -0
  37. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/rsa/RSAKey.as +339 -0
  38. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/AESKey.as +2797 -0
  39. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/BlowFishKey.as +375 -0
  40. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CBCMode.as +55 -0
  41. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFB8Mode.as +61 -0
  42. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFBMode.as +64 -0
  43. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CTRMode.as +58 -0
  44. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/DESKey.as +365 -0
  45. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ECBMode.as +86 -0
  46. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ICipher.as +21 -0
  47. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IMode.as +15 -0
  48. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IPad.as +32 -0
  49. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IStreamCipher.as +21 -0
  50. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ISymmetricKey.as +35 -0
  51. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IVMode.as +110 -0
  52. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/NullPad.as +34 -0
  53. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/OFBMode.as +52 -0
  54. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/PKCS5.as +44 -0
  55. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SSLPad.as +44 -0
  56. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SimpleIVMode.as +60 -0
  57. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TLSPad.as +42 -0
  58. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TripleDESKey.as +88 -0
  59. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/XTeaKey.as +94 -0
  60. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/aeskey.pl +29 -0
  61. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/dump.txt +2304 -0
  62. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/AESKeyTest.as +1220 -0
  63. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ARC4Test.as +58 -0
  64. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BigIntegerTest.as +39 -0
  65. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BlowFishKeyTest.as +148 -0
  66. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CBCModeTest.as +160 -0
  67. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFB8ModeTest.as +71 -0
  68. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFBModeTest.as +98 -0
  69. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CTRModeTest.as +109 -0
  70. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/DESKeyTest.as +112 -0
  71. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ECBModeTest.as +151 -0
  72. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/HMACTest.as +184 -0
  73. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ITestHarness.as +20 -0
  74. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD2Test.as +56 -0
  75. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD5Test.as +58 -0
  76. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/OFBModeTest.as +101 -0
  77. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/RSAKeyTest.as +92 -0
  78. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA1Test.as +198 -0
  79. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA224Test.as +58 -0
  80. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA256Test.as +60 -0
  81. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TLSPRFTest.as +51 -0
  82. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TestCase.as +42 -0
  83. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TripleDESKeyTest.as +59 -0
  84. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/XTeaKeyTest.as +66 -0
  85. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/BulkCiphers.as +102 -0
  86. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/CipherSuites.as +117 -0
  87. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/IConnectionState.as +14 -0
  88. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/ISecurityParameters.as +29 -0
  89. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/KeyExchanges.as +24 -0
  90. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/MACs.as +38 -0
  91. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLConnectionState.as +171 -0
  92. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLEvent.as +26 -0
  93. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as +340 -0
  94. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConfig.as +70 -0
  95. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConnectionState.as +151 -0
  96. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEngine.as +895 -0
  97. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSError.as +39 -0
  98. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEvent.as +27 -0
  99. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSecurityParameters.as +197 -0
  100. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocket.as +370 -0
  101. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocketEvent.as +26 -0
  102. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSTest.as +180 -0
  103. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BarrettReduction.as +90 -0
  104. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BigInteger.as +1543 -0
  105. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/ClassicReduction.as +35 -0
  106. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/IReduction.as +11 -0
  107. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/MontgomeryReduction.as +85 -0
  108. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/NullReduction.as +34 -0
  109. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/bi_internal.as +11 -0
  110. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/ArrayUtil.as +25 -0
  111. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Base64.as +189 -0
  112. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Hex.as +66 -0
  113. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Memory.as +28 -0
  114. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ByteString.as +43 -0
  115. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/DER.as +210 -0
  116. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/IAsn1Type.as +21 -0
  117. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Integer.as +44 -0
  118. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/OID.as +35 -0
  119. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ObjectIdentifier.as +112 -0
  120. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PEM.as +118 -0
  121. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PrintableString.as +49 -0
  122. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Sequence.as +90 -0
  123. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Set.as +27 -0
  124. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Type.as +94 -0
  125. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/UTCTime.as +60 -0
  126. data/src/vendor/web-socket-js/sample.html +76 -0
  127. data/src/vendor/web-socket-js/swfobject.js +4 -0
  128. data/src/vendor/web-socket-js/web_socket.js +388 -0
  129. metadata +163 -30
  130. data/lib/rocket/js/version.rb +0 -14
  131. data/rocket-0.0.1.min.js +0 -45
@@ -0,0 +1,26 @@
1
+ /**
2
+ * TLSEvent
3
+ *
4
+ * This is used by TLSEngine to let the application layer know
5
+ * when we're ready for sending, or have received application data
6
+ * Copyright (c) 2007 Henri Torgemane
7
+ *
8
+ * See LICENSE.txt for full license information.
9
+ */
10
+ package com.hurlant.crypto.tls {
11
+ import flash.events.Event;
12
+ import flash.utils.ByteArray;
13
+ import com.hurlant.crypto.cert.X509Certificate;
14
+
15
+ public class TLSSocketEvent extends Event {
16
+
17
+ static public const PROMPT_ACCEPT_CERT:String = "promptAcceptCert";
18
+
19
+ public var cert:X509Certificate;
20
+
21
+ public function TLSSocketEvent( cert:X509Certificate = null) {
22
+ super(PROMPT_ACCEPT_CERT, false, false);
23
+ this.cert = cert;
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,180 @@
1
+ /**
2
+ * TLSTest
3
+ *
4
+ * A test class for TLS. Not a finished product.
5
+ * Copyright (c) 2007 Henri Torgemane
6
+ *
7
+ * See LICENSE.txt for full license information.
8
+ */
9
+ package com.hurlant.crypto.tls {
10
+ import com.hurlant.crypto.cert.X509Certificate;
11
+ import com.hurlant.crypto.cert.X509CertificateCollection;
12
+ import com.hurlant.util.Hex;
13
+ import com.hurlant.util.der.PEM;
14
+
15
+ import flash.events.Event;
16
+ import flash.events.ProgressEvent;
17
+ import flash.net.Socket;
18
+ import flash.utils.ByteArray;
19
+ import flash.utils.getTimer;
20
+
21
+ public class TLSTest {
22
+
23
+
24
+ public var myDebugData:String;
25
+
26
+ //[Embed(source="/src/host.cert",mimeType="application/octet-stream")]
27
+ public var myCert:Class;
28
+ //[Embed(source="/src/host.key",mimeType="application/octet-stream")]
29
+ public var myKey:Class;
30
+
31
+ public function TLSTest(host:String = null, port:int = 0, type:int = 0 ) {
32
+ //loopback();
33
+ if (host != null) {
34
+ if (type == 0) { // SSL 3.0
35
+ connectLoginYahooCom();
36
+ // connectLocalSSL(host, port);
37
+ } else {
38
+ connectLocalTLS(host, port);
39
+ }
40
+ } else {
41
+ testSocket();
42
+ }
43
+ }
44
+
45
+ public function connectLoginYahooCom():void {
46
+ trace("Connecting test socket");
47
+ var s:Socket = new Socket("esx.bluebearllc.net", 903);
48
+
49
+ var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT,
50
+ null,
51
+ null,
52
+ null,
53
+ null,
54
+ null,
55
+ SSLSecurityParameters.PROTOCOL_VERSION);
56
+
57
+ var client:TLSEngine = new TLSEngine(clientConfig, s, s);
58
+ // hook some events.
59
+ s.addEventListener(ProgressEvent.SOCKET_DATA, client.dataAvailable);
60
+ client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { s.flush(); });
61
+ client.start();
62
+
63
+ }
64
+ public function connectLocalTLS(host:String, port:int):void {
65
+ var s:Socket = new Socket(host, port);
66
+
67
+ var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT);
68
+
69
+ var client:TLSEngine = new TLSEngine(clientConfig, s, s);
70
+ // hook some events.
71
+ s.addEventListener(ProgressEvent.SOCKET_DATA, client.dataAvailable);
72
+ client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { s.flush(); });
73
+
74
+ client.start();
75
+
76
+ }
77
+ public function connectLocalSSL(host:String, port:int):void {
78
+ var s:Socket = new Socket(host, port);
79
+
80
+ var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT,
81
+ null,
82
+ null,
83
+ null,
84
+ null,
85
+ null,
86
+ SSLSecurityParameters.PROTOCOL_VERSION);
87
+
88
+ var client:TLSEngine = new TLSEngine(clientConfig, s, s);
89
+ // hook some events.
90
+ s.addEventListener(ProgressEvent.SOCKET_DATA, client.dataAvailable);
91
+ client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { s.flush(); });
92
+
93
+ client.start();
94
+ }
95
+
96
+ public function loopback():void {
97
+
98
+ var server_write:ByteArray = new ByteArray;
99
+ var client_write:ByteArray = new ByteArray;
100
+ var server_write_cursor:uint = 0;
101
+ var client_write_cursor:uint = 0;
102
+
103
+ var clientConfig:TLSConfig = new TLSConfig(TLSEngine.CLIENT, null, null, null, null, null, SSLSecurityParameters.PROTOCOL_VERSION);
104
+ var serverConfig:TLSConfig = new TLSConfig(TLSEngine.SERVER, null, null, null, null, null, SSLSecurityParameters.PROTOCOL_VERSION);
105
+
106
+
107
+ var cert:ByteArray = new myCert;
108
+ var key:ByteArray = new myKey;
109
+ serverConfig.setPEMCertificate(cert.readUTFBytes(cert.length), key.readUTFBytes(key.length));
110
+ // tmp, for debugging. currently useless
111
+ cert.position = 0;
112
+ key.position = 0;
113
+ clientConfig.setPEMCertificate(cert.readUTFBytes(cert.length), key.readUTFBytes(key.length));
114
+ // put the server cert in the client's trusted store, to keep things happy.
115
+ clientConfig.CAStore = new X509CertificateCollection;
116
+ cert.position = 0;
117
+ var x509:X509Certificate = new X509Certificate(PEM.readCertIntoArray(cert.readUTFBytes(cert.length)));
118
+ clientConfig.CAStore.addCertificate(x509);
119
+
120
+
121
+ var server:TLSEngine = new TLSEngine(serverConfig, client_write, server_write);
122
+ var client:TLSEngine = new TLSEngine(clientConfig, server_write, client_write);
123
+
124
+ server.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*=null):void {
125
+ trace("server wrote something!");
126
+ trace(Hex.fromArray(server_write));
127
+ var l:uint = server_write.position;
128
+ server_write.position = server_write_cursor;
129
+ client.dataAvailable(e);
130
+ server_write.position = l;
131
+ server_write_cursor = l;
132
+ });
133
+ client.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*=null):void {
134
+ trace("client wrote something!");
135
+ trace(Hex.fromArray(client_write));
136
+ var l:uint = client_write.position;
137
+ client_write.position = client_write_cursor;
138
+ server.dataAvailable(e);
139
+ client_write.position = l;
140
+ client_write_cursor = l;
141
+ });
142
+
143
+ server.start();
144
+ client.start();
145
+ }
146
+
147
+ public function testSocket():void {
148
+ var hosts:Array = [
149
+ "bugs.adobe.com", // apache
150
+ "login.yahoo.com", // apache, bigger response
151
+ "login.live.com", // IIS-6, chain of 3 certs
152
+ "banking.wellsfargo.com", // custom, sends its CA cert along for the ride.
153
+ "www.bankofamerica.com" // sun-one, chain of 3 certs
154
+ ];
155
+ var i:int =0;
156
+ (function next():void {
157
+ testHost(hosts[i++], next);
158
+ })();
159
+ }
160
+
161
+ private function testHost(host:String, next:Function):void {
162
+ if (host==null) return;
163
+ var t1:int = getTimer();
164
+
165
+ var host:String = host;
166
+ var t:TLSSocket = new TLSSocket;
167
+ t.connect(host, 4433);
168
+ t.writeUTFBytes("GET / HTTP/1.0\nHost: "+host+"\n\n");
169
+ t.addEventListener(Event.CLOSE, function(e:*):void {
170
+ var s:String = t.readUTFBytes(t.bytesAvailable);
171
+ trace("Response from "+host+": "+s.length+" characters");
172
+ var bytes:ByteArray = new ByteArray();
173
+ t.readBytes(bytes, 0, t.bytesAvailable);
174
+ trace(Hex.fromArray(bytes));
175
+ trace("Time used = "+(getTimer()-t1)+"ms");
176
+ next();
177
+ });
178
+ }
179
+ }
180
+ }
@@ -0,0 +1,90 @@
1
+ package com.hurlant.math
2
+ {
3
+ use namespace bi_internal;
4
+
5
+ internal class BarrettReduction implements IReduction
6
+ {
7
+ private var m:BigInteger;
8
+ private var r2:BigInteger;
9
+ private var q3:BigInteger;
10
+ private var mu:BigInteger;
11
+
12
+ public function BarrettReduction(m:BigInteger) {
13
+ // setup Barrett
14
+ r2 = new BigInteger;
15
+ q3 = new BigInteger;
16
+ BigInteger.ONE.dlShiftTo(2*m.t, r2);
17
+ mu = r2.divide(m);
18
+ this.m = m;
19
+ }
20
+
21
+ public function revert(x:BigInteger):BigInteger
22
+ {
23
+ return x;
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @param x
29
+ * @param y
30
+ * @param r = x*y mod m; x != r
31
+ *
32
+ */
33
+ public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void
34
+ {
35
+ x.multiplyTo(y, r);
36
+ reduce(r);
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @param x
42
+ * @param r = x^2 mod m; x != r
43
+ *
44
+ */
45
+ public function sqrTo(x:BigInteger, r:BigInteger):void
46
+ {
47
+ x.squareTo(r);
48
+ reduce(r);
49
+ }
50
+
51
+ public function convert(x:BigInteger):BigInteger
52
+ {
53
+ if (x.s<0 || x.t>2*m.t) {
54
+ return x.mod(m);
55
+ } else if (x.compareTo(m)<0) {
56
+ return x;
57
+ } else {
58
+ var r:BigInteger = new BigInteger;
59
+ x.copyTo(r);
60
+ reduce(r);
61
+ return r;
62
+ }
63
+ }
64
+
65
+ /**
66
+ *
67
+ * @param x = x mod m (HAC 14.42)
68
+ *
69
+ */
70
+ public function reduce(lx:BigInteger):void
71
+ {
72
+ var x:BigInteger = lx as BigInteger;
73
+ x.drShiftTo(m.t-1,r2);
74
+ if (x.t>m.t+1) {
75
+ x.t = m.t+1;
76
+ x.clamp();
77
+ }
78
+ mu.multiplyUpperTo(r2, m.t+1, q3);
79
+ m.multiplyLowerTo(q3, m.t+1, r2);
80
+ while (x.compareTo(r2)<0) {
81
+ x.dAddOffset(1, m.t+1);
82
+ }
83
+ x.subTo(r2,x);
84
+ while (x.compareTo(m)>=0) {
85
+ x.subTo(m,x);
86
+ }
87
+ }
88
+
89
+ }
90
+ }
@@ -0,0 +1,1543 @@
1
+ /**
2
+ * BigInteger
3
+ *
4
+ * An ActionScript 3 implementation of BigInteger (light version)
5
+ * Copyright (c) 2007 Henri Torgemane
6
+ *
7
+ * Derived from:
8
+ * The jsbn library, Copyright (c) 2003-2005 Tom Wu
9
+ *
10
+ * See LICENSE.txt for full license information.
11
+ */
12
+ package com.hurlant.math
13
+ {
14
+
15
+ import com.hurlant.crypto.prng.Random;
16
+ import com.hurlant.util.Hex;
17
+ import com.hurlant.util.Memory;
18
+
19
+ import flash.utils.ByteArray;
20
+ use namespace bi_internal;
21
+
22
+ public class BigInteger
23
+ {
24
+ public static const DB:int = 30; // number of significant bits per chunk
25
+ public static const DV:int = (1<<DB);
26
+ public static const DM:int = (DV-1); // Max value in a chunk
27
+
28
+ public static const BI_FP:int = 52;
29
+ public static const FV:Number = Math.pow(2, BI_FP);
30
+ public static const F1:int = BI_FP - DB;
31
+ public static const F2:int = 2*DB - BI_FP;
32
+
33
+ public static const ZERO:BigInteger = nbv(0);
34
+ public static const ONE:BigInteger = nbv(1);
35
+
36
+ /*bi_internal */public var t:int; // number of chunks.
37
+ bi_internal var s:int; // sign
38
+ bi_internal var a:Array; // chunks
39
+
40
+ /**
41
+ *
42
+ * @param value
43
+ * @param radix WARNING: If value is ByteArray, this holds the number of bytes to use.
44
+ * @param unsigned
45
+ *
46
+ */
47
+ public function BigInteger(value:* = null, radix:int = 0, unsigned:Boolean = false) {
48
+ a = new Array;
49
+ if (value is String) {
50
+ if (radix&&radix!=16) throw new Error("BigInteger construction with radix!=16 is not supported.");
51
+ value = Hex.toArray(value);
52
+ radix=0;
53
+ }
54
+ if (value is ByteArray) {
55
+ var array:ByteArray = value as ByteArray;
56
+ var length:int = radix || (array.length - array.position);
57
+ fromArray(array, length, unsigned);
58
+ }
59
+ }
60
+ public function dispose():void {
61
+ var r:Random = new Random;
62
+ for (var i:uint=0;i<a.length;i++) {
63
+ a[i] = r.nextByte();
64
+ delete a[i];
65
+ }
66
+ a=null;
67
+ t=0;
68
+ s=0;
69
+ Memory.gc();
70
+ }
71
+
72
+ public function toString(radix:Number=16):String {
73
+ if (s<0) return "-"+negate().toString(radix);
74
+ var k:int;
75
+ switch (radix) {
76
+ case 2: k=1; break;
77
+ case 4: k=2; break;
78
+ case 8: k=3; break;
79
+ case 16: k=4; break;
80
+ case 32: k=5; break;
81
+ default:
82
+ // return toRadix(radix);
83
+ }
84
+ var km:int = (1<<k)-1;
85
+ var d:int = 0;
86
+ var m:Boolean = false;
87
+ var r:String = "";
88
+ var i:int = t;
89
+ var p:int = DB-(i*DB)%k;
90
+ if (i-->0) {
91
+ if (p<DB && (d=a[i]>>p)>0) {
92
+ m = true;
93
+ r = d.toString(36);
94
+ }
95
+ while (i >= 0) {
96
+ if (p<k) {
97
+ d = (a[i]&((1<<p)-1))<<(k-p);
98
+ d|= a[--i]>>(p+=DB-k);
99
+ } else {
100
+ d = (a[i]>>(p-=k))&km;
101
+ if (p<=0) {
102
+ p += DB;
103
+ --i;
104
+ }
105
+ }
106
+ if (d>0) {
107
+ m = true;
108
+ }
109
+ if (m) {
110
+ r += d.toString(36);
111
+ }
112
+ }
113
+ }
114
+ return m?r:"0";
115
+ }
116
+ public function toArray(array:ByteArray):uint {
117
+ const k:int = 8;
118
+ const km:int = (1<<8)-1;
119
+ var d:int = 0;
120
+ var i:int = t;
121
+ var p:int = DB-(i*DB)%k;
122
+ var m:Boolean = false;
123
+ var c:int = 0;
124
+ if (i-->0) {
125
+ if (p<DB && (d=a[i]>>p)>0) {
126
+ m = true;
127
+ array.writeByte(d);
128
+ c++;
129
+ }
130
+ while (i >= 0) {
131
+ if (p<k) {
132
+ d = (a[i]&((1<<p)-1))<<(k-p);
133
+ d|= a[--i]>>(p+=DB-k);
134
+ } else {
135
+ d = (a[i]>>(p-=k))&km;
136
+ if (p<=0) {
137
+ p += DB;
138
+ --i;
139
+ }
140
+ }
141
+ if (d>0) {
142
+ m = true;
143
+ }
144
+ if (m) {
145
+ array.writeByte(d);
146
+ c++;
147
+ }
148
+ }
149
+ }
150
+ return c;
151
+ }
152
+ /**
153
+ * best-effort attempt to fit into a Number.
154
+ * precision can be lost if it just can't fit.
155
+ */
156
+ public function valueOf():Number {
157
+ if (s==-1) {
158
+ return -negate().valueOf();
159
+ }
160
+ var coef:Number = 1;
161
+ var value:Number = 0;
162
+ for (var i:uint=0;i<t;i++) {
163
+ value += a[i]*coef;
164
+ coef *= DV;
165
+ }
166
+ return value;
167
+ }
168
+ /**
169
+ * -this
170
+ */
171
+ public function negate():BigInteger {
172
+ var r:BigInteger = nbi();
173
+ ZERO.subTo(this, r);
174
+ return r;
175
+ }
176
+ /**
177
+ * |this|
178
+ */
179
+ public function abs():BigInteger {
180
+ return (s<0)?negate():this;
181
+ }
182
+ /**
183
+ * return + if this > v, - if this < v, 0 if equal
184
+ */
185
+ public function compareTo(v:BigInteger):int {
186
+ var r:int = s - v.s;
187
+ if (r!=0) {
188
+ return r;
189
+ }
190
+ var i:int = t;
191
+ r = i-v.t;
192
+ if (r!=0) {
193
+ return r;
194
+ }
195
+ while (--i >=0) {
196
+ r=a[i]-v.a[i];
197
+ if (r != 0) return r;
198
+ }
199
+ return 0;
200
+ }
201
+ /**
202
+ * returns bit length of the integer x
203
+ */
204
+ bi_internal function nbits(x:int):int {
205
+ var r:int = 1;
206
+ var t:int;
207
+ if ((t=x>>>16) != 0) { x = t; r += 16; }
208
+ if ((t=x>>8) != 0) { x = t; r += 8; }
209
+ if ((t=x>>4) != 0) { x = t; r += 4; }
210
+ if ((t=x>>2) != 0) { x = t; r += 2; }
211
+ if ((t=x>>1) != 0) { x = t; r += 1; }
212
+ return r;
213
+ }
214
+ /**
215
+ * returns the number of bits in this
216
+ */
217
+ public function bitLength():int {
218
+ if (t<=0) return 0;
219
+ return DB*(t-1)+nbits(a[t-1]^(s&DM));
220
+ }
221
+ /**
222
+ *
223
+ * @param v
224
+ * @return this % v
225
+ *
226
+ */
227
+ public function mod(v:BigInteger):BigInteger {
228
+ var r:BigInteger = nbi();
229
+ abs().divRemTo(v,null,r);
230
+ if (s<0 && r.compareTo(ZERO)>0) {
231
+ v.subTo(r,r);
232
+ }
233
+ return r;
234
+ }
235
+ /**
236
+ * this^e % m, 0 <= e < 2^32
237
+ */
238
+ public function modPowInt(e:int, m:BigInteger):BigInteger {
239
+ var z:IReduction;
240
+ if (e<256 || m.isEven()) {
241
+ z = new ClassicReduction(m);
242
+ } else {
243
+ z = new MontgomeryReduction(m);
244
+ }
245
+ return exp(e, z);
246
+ }
247
+
248
+ /**
249
+ * copy this to r
250
+ */
251
+ bi_internal function copyTo(r:BigInteger):void {
252
+ for (var i:int = t-1; i>=0; --i) {
253
+ r.a[i] = a[i];
254
+ }
255
+ r.t = t;
256
+ r.s = s;
257
+ }
258
+ /**
259
+ * set from integer value "value", -DV <= value < DV
260
+ */
261
+ bi_internal function fromInt(value:int):void {
262
+ t = 1;
263
+ s = (value<0)?-1:0;
264
+ if (value>0) {
265
+ a[0] = value;
266
+ } else if (value<-1) {
267
+ a[0] = value+DV;
268
+ } else {
269
+ t = 0;
270
+ }
271
+ }
272
+ /**
273
+ * set from ByteArray and length,
274
+ * starting a current position
275
+ * If length goes beyond the array, pad with zeroes.
276
+ */
277
+ bi_internal function fromArray(value:ByteArray, length:int, unsigned:Boolean = false):void {
278
+ var p:int = value.position;
279
+ var i:int = p+length;
280
+ var sh:int = 0;
281
+ const k:int = 8;
282
+ t = 0;
283
+ s = 0;
284
+ while (--i >= p) {
285
+ var x:int = i<value.length?value[i]:0;
286
+ if (sh == 0) {
287
+ a[t++] = x;
288
+ } else if (sh+k > DB) {
289
+ a[t-1] |= (x&((1<<(DB-sh))-1))<<sh;
290
+ a[t++] = x>>(DB-sh);
291
+ } else {
292
+ a[t-1] |= x<<sh;
293
+ }
294
+ sh += k;
295
+ if (sh >= DB) sh -= DB;
296
+ }
297
+ if (!unsigned && (value[0]&0x80)==0x80) {
298
+ s = -1;
299
+ if (sh > 0) {
300
+ a[t-1] |= ((1<<(DB-sh))-1)<<sh;
301
+ }
302
+ }
303
+ clamp();
304
+ value.position = Math.min(p+length,value.length);
305
+ }
306
+ /**
307
+ * clamp off excess high words
308
+ */
309
+ bi_internal function clamp():void {
310
+ var c:int = s&DM;
311
+ while (t>0 && a[t-1]==c) {
312
+ --t;
313
+ }
314
+ }
315
+ /**
316
+ * r = this << n*DB
317
+ */
318
+ bi_internal function dlShiftTo(n:int, r:BigInteger):void {
319
+ var i:int;
320
+ for (i=t-1; i>=0; --i) {
321
+ r.a[i+n] = a[i];
322
+ }
323
+ for (i=n-1; i>=0; --i) {
324
+ r.a[i] = 0;
325
+ }
326
+ r.t = t+n;
327
+ r.s = s;
328
+ }
329
+ /**
330
+ * r = this >> n*DB
331
+ */
332
+ bi_internal function drShiftTo(n:int, r:BigInteger):void {
333
+ var i:int;
334
+ for (i=n; i<t; ++i) {
335
+ r.a[i-n] = a[i];
336
+ }
337
+ r.t = Math.max(t-n,0);
338
+ r.s = s;
339
+ }
340
+ /**
341
+ * r = this << n
342
+ */
343
+ bi_internal function lShiftTo(n:int, r:BigInteger):void {
344
+ var bs:int = n%DB;
345
+ var cbs:int = DB-bs;
346
+ var bm:int = (1<<cbs)-1;
347
+ var ds:int = n/DB;
348
+ var c:int = (s<<bs)&DM;
349
+ var i:int;
350
+ for (i=t-1; i>=0; --i) {
351
+ r.a[i+ds+1] = (a[i]>>cbs)|c;
352
+ c = (a[i]&bm)<<bs;
353
+ }
354
+ for (i=ds-1; i>=0; --i) {
355
+ r.a[i] = 0;
356
+ }
357
+ r.a[ds] = c;
358
+ r.t = t+ds+1;
359
+ r.s = s;
360
+ r.clamp();
361
+ }
362
+ /**
363
+ * r = this >> n
364
+ */
365
+ bi_internal function rShiftTo(n:int, r:BigInteger):void {
366
+ r.s = s;
367
+ var ds:int = n/DB;
368
+ if (ds >= t) {
369
+ r.t = 0;
370
+ return;
371
+ }
372
+ var bs:int = n%DB;
373
+ var cbs:int = DB-bs;
374
+ var bm:int = (1<<bs)-1;
375
+ r.a[0] = a[ds]>>bs;
376
+ var i:int;
377
+ for (i=ds+1; i<t; ++i) {
378
+ r.a[i-ds-1] |= (a[i]&bm)<<cbs;
379
+ r.a[i-ds] = a[i]>>bs;
380
+ }
381
+ if (bs>0) {
382
+ r.a[t-ds-1] |= (s&bm)<<cbs;
383
+ }
384
+ r.t = t-ds;
385
+ r.clamp();
386
+ }
387
+ /**
388
+ * r = this - v
389
+ */
390
+ bi_internal function subTo(v:BigInteger, r:BigInteger):void {
391
+ var i:int = 0;
392
+ var c:int = 0;
393
+ var m:int = Math.min(v.t, t);
394
+ while (i<m) {
395
+ c += a[i] - v.a[i];
396
+ r.a[i++] = c & DM;
397
+ c >>= DB;
398
+ }
399
+ if (v.t < t) {
400
+ c -= v.s;
401
+ while (i< t) {
402
+ c+= a[i];
403
+ r.a[i++] = c&DM;
404
+ c >>= DB;
405
+ }
406
+ c += s;
407
+ } else {
408
+ c += s;
409
+ while (i < v.t) {
410
+ c -= v.a[i];
411
+ r.a[i++] = c&DM;
412
+ c >>= DB;
413
+ }
414
+ c -= v.s;
415
+ }
416
+ r.s = (c<0)?-1:0;
417
+ if (c<-1) {
418
+ r.a[i++] = DV+c;
419
+ } else if (c>0) {
420
+ r.a[i++] = c;
421
+ }
422
+ r.t = i;
423
+ r.clamp();
424
+ }
425
+ /**
426
+ * am: Compute w_j += (x*this_i), propagates carries,
427
+ * c is initial carry, returns final carry.
428
+ * c < 3*dvalue, x < 2*dvalue, this_i < dvalue
429
+ */
430
+ bi_internal function am(i:int,x:int,w:BigInteger,j:int,c:int,n:int):int {
431
+ var xl:int = x&0x7fff;
432
+ var xh:int = x>>15;
433
+ while(--n >= 0) {
434
+ var l:int = a[i]&0x7fff;
435
+ var h:int = a[i++]>>15;
436
+ var m:int = xh*l + h*xl;
437
+ l = xl*l + ((m&0x7fff)<<15)+w.a[j]+(c&0x3fffffff);
438
+ c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
439
+ w.a[j++] = l&0x3fffffff;
440
+ }
441
+ return c;
442
+ }
443
+ /**
444
+ * r = this * v, r != this,a (HAC 14.12)
445
+ * "this" should be the larger one if appropriate
446
+ */
447
+ bi_internal function multiplyTo(v:BigInteger, r:BigInteger):void {
448
+ var x:BigInteger = abs();
449
+ var y:BigInteger = v.abs();
450
+ var i:int = x.t;
451
+ r.t = i+y.t;
452
+ while (--i >= 0) {
453
+ r.a[i] = 0;
454
+ }
455
+ for (i=0; i<y.t; ++i) {
456
+ r.a[i+x.t] = x.am(0, y.a[i], r, i, 0, x.t);
457
+ }
458
+ r.s = 0;
459
+ r.clamp();
460
+ if (s!=v.s) {
461
+ ZERO.subTo(r, r);
462
+ }
463
+ }
464
+ /**
465
+ * r = this^2, r != this (HAC 14.16)
466
+ */
467
+ bi_internal function squareTo(r:BigInteger):void {
468
+ var x:BigInteger = abs();
469
+ var i:int = r.t = 2*x.t;
470
+ while (--i>=0) r.a[i] = 0;
471
+ for (i=0; i<x.t-1; ++i) {
472
+ var c:int = x.am(i, x.a[i], r, 2*i, 0, 1);
473
+ if ((r.a[i+x.t] += x.am(i+1, 2*x.a[i], r, 2*i+1, c, x.t-i-1)) >= DV) {
474
+ r.a[i+x.t] -= DV;
475
+ r.a[i+x.t+1] = 1;
476
+ }
477
+ }
478
+ if (r.t>0) {
479
+ r.a[r.t-1] += x.am(i, x.a[i], r, 2*i, 0, 1);
480
+ }
481
+ r.s = 0;
482
+ r.clamp();
483
+ }
484
+ /**
485
+ * divide this by m, quotient and remainder to q, r (HAC 14.20)
486
+ * r != q, this != m. q or r may be null.
487
+ */
488
+ bi_internal function divRemTo(m:BigInteger, q:BigInteger = null, r:BigInteger = null):void {
489
+ var pm:BigInteger = m.abs();
490
+ if (pm.t <= 0) return;
491
+ var pt:BigInteger = abs();
492
+ if (pt.t < pm.t) {
493
+ if (q!=null) q.fromInt(0);
494
+ if (r!=null) copyTo(r);
495
+ return;
496
+ }
497
+ if (r==null) r = nbi();
498
+ var y:BigInteger = nbi();
499
+ var ts:int = s;
500
+ var ms:int = m.s;
501
+ var nsh:int = DB-nbits(pm.a[pm.t-1]); // normalize modulus
502
+ if (nsh>0) {
503
+ pm.lShiftTo(nsh, y);
504
+ pt.lShiftTo(nsh, r);
505
+ } else {
506
+ pm.copyTo(y);
507
+ pt.copyTo(r);
508
+ }
509
+ var ys:int = y.t;
510
+ var y0:int = y.a[ys-1];
511
+ if (y0==0) return;
512
+ var yt:Number = y0*(1<<F1)+((ys>1)?y.a[ys-2]>>F2:0);
513
+ var d1:Number = FV/yt;
514
+ var d2:Number = (1<<F1)/yt;
515
+ var e:Number = 1<<F2;
516
+ var i:int = r.t;
517
+ var j:int = i-ys;
518
+ var t:BigInteger = (q==null)?nbi():q;
519
+ y.dlShiftTo(j,t);
520
+ if (r.compareTo(t)>=0) {
521
+ r.a[r.t++] = 1;
522
+ r.subTo(t,r);
523
+ }
524
+ ONE.dlShiftTo(ys,t);
525
+ t.subTo(y,y); // "negative" y so we can replace sub with am later.
526
+ while(y.t<ys) y.(y.t++, 0);
527
+ while(--j >= 0) {
528
+ // Estimate quotient digit
529
+ var qd:int = (r.a[--i]==y0)?DM:Number(r.a[i])*d1+(Number(r.a[i-1])+e)*d2;
530
+ if ((r.a[i]+= y.am(0, qd, r, j, 0, ys))<qd) { // Try it out
531
+ y.dlShiftTo(j, t);
532
+ r.subTo(t,r);
533
+ while (r.a[i]<--qd) {
534
+ r.subTo(t,r);
535
+ }
536
+ }
537
+ }
538
+ if (q!=null) {
539
+ r.drShiftTo(ys,q);
540
+ if (ts!=ms) {
541
+ ZERO.subTo(q,q);
542
+ }
543
+ }
544
+ r.t = ys;
545
+ r.clamp();
546
+ if (nsh>0) {
547
+ r.rShiftTo(nsh, r); // Denormalize remainder
548
+ }
549
+ if (ts<0) {
550
+ ZERO.subTo(r,r);
551
+ }
552
+ }
553
+ /**
554
+ * return "-1/this % 2^DB"; useful for Mont. reduction
555
+ * justification:
556
+ * xy == 1 (mod n)
557
+ * xy = 1+km
558
+ * xy(2-xy) = (1+km)(1-km)
559
+ * x[y(2-xy)] = 1-k^2.m^2
560
+ * x[y(2-xy)] == 1 (mod m^2)
561
+ * if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
562
+ * should reduce x and y(2-xy) by m^2 at each step to keep size bounded
563
+ * [XXX unit test the living shit out of this.]
564
+ */
565
+ bi_internal function invDigit():int {
566
+ if (t<1) return 0;
567
+ var x:int = a[0];
568
+ if ((x&1)==0) return 0;
569
+ var y:int = x&3; // y == 1/x mod 2^2
570
+ y = (y*(2-(x&0xf )*y)) &0xf; // y == 1/x mod 2^4
571
+ y = (y*(2-(x&0xff)*y)) &0xff; // y == 1/x mod 2^8
572
+ y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
573
+ // last step - calculate inverse mod DV directly;
574
+ // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
575
+ // XXX 48 bit ints? Whaaaa? is there an implicit float conversion in here?
576
+ y = (y*(2-x*y%DV))%DV; // y == 1/x mod 2^dbits
577
+ // we really want the negative inverse, and -DV < y < DV
578
+ return (y>0)?DV-y:-y;
579
+ }
580
+ /**
581
+ * true iff this is even
582
+ */
583
+ bi_internal function isEven():Boolean {
584
+ return ((t>0)?(a[0]&1):s) == 0;
585
+ }
586
+ /**
587
+ * this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
588
+ */
589
+ bi_internal function exp(e:int, z:IReduction):BigInteger {
590
+ if (e > 0xffffffff || e < 1) return ONE;
591
+ var r:BigInteger = nbi();
592
+ var r2:BigInteger = nbi();
593
+ var g:BigInteger = z.convert(this);
594
+ var i:int = nbits(e)-1;
595
+ g.copyTo(r);
596
+ while(--i>=0) {
597
+ z.sqrTo(r, r2);
598
+ if ((e&(1<<i))>0) {
599
+ z.mulTo(r2,g,r);
600
+ } else {
601
+ var t:BigInteger = r;
602
+ r = r2;
603
+ r2 = t;
604
+ }
605
+
606
+ }
607
+ return z.revert(r);
608
+ }
609
+ bi_internal function intAt(str:String, index:int):int {
610
+ return parseInt(str.charAt(index), 36);
611
+ }
612
+
613
+
614
+ protected function nbi():* {
615
+ return new BigInteger;
616
+ }
617
+ /**
618
+ * return bigint initialized to value
619
+ */
620
+ public static function nbv(value:int):BigInteger {
621
+ var bn:BigInteger = new BigInteger;
622
+ bn.fromInt(value);
623
+ return bn;
624
+ }
625
+
626
+
627
+ // Functions above are sufficient for RSA encryption.
628
+ // The stuff below is useful for decryption and key generation
629
+
630
+ public static const lowprimes:Array = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
631
+ public static const lplim:int = (1<<26)/lowprimes[lowprimes.length-1];
632
+
633
+
634
+ public function clone():BigInteger {
635
+ var r:BigInteger = new BigInteger;
636
+ this.copyTo(r);
637
+ return r;
638
+ }
639
+
640
+ /**
641
+ *
642
+ * @return value as integer
643
+ *
644
+ */
645
+ public function intValue():int {
646
+ if (s<0) {
647
+ if (t==1) {
648
+ return a[0]-DV;
649
+ } else if (t==0) {
650
+ return -1;
651
+ }
652
+ } else if (t==1) {
653
+ return a[0];
654
+ } else if (t==0) {
655
+ return 0;
656
+ }
657
+ // assumes 16 < DB < 32
658
+ return ((a[1]&((1<<(32-DB))-1))<<DB)|a[0];
659
+ }
660
+
661
+ /**
662
+ *
663
+ * @return value as byte
664
+ *
665
+ */
666
+ public function byteValue():int {
667
+ return (t==0)?s:(a[0]<<24)>>24;
668
+ }
669
+
670
+ /**
671
+ *
672
+ * @return value as short (assumes DB>=16)
673
+ *
674
+ */
675
+ public function shortValue():int {
676
+ return (t==0)?s:(a[0]<<16)>>16;
677
+ }
678
+
679
+ /**
680
+ *
681
+ * @param r
682
+ * @return x s.t. r^x < DV
683
+ *
684
+ */
685
+ protected function chunkSize(r:Number):int {
686
+ return Math.floor(Math.LN2*DB/Math.log(r));
687
+ }
688
+
689
+ /**
690
+ *
691
+ * @return 0 if this ==0, 1 if this >0
692
+ *
693
+ */
694
+ public function sigNum():int {
695
+ if (s<0) {
696
+ return -1;
697
+ } else if (t<=0 || (t==1 && a[0]<=0)) {
698
+ return 0;
699
+ } else{
700
+ return 1;
701
+ }
702
+ }
703
+
704
+ /**
705
+ *
706
+ * @param b: radix to use
707
+ * @return a string representing the integer converted to the radix.
708
+ *
709
+ */
710
+ protected function toRadix(b:uint=10):String {
711
+ if (sigNum()==0 || b<2 || b>32) return "0";
712
+ var cs:int = chunkSize(b);
713
+ var a:Number = Math.pow(b, cs);
714
+ var d:BigInteger = nbv(a);
715
+ var y:BigInteger = nbi();
716
+ var z:BigInteger = nbi();
717
+ var r:String = "";
718
+ divRemTo(d, y, z);
719
+ while (y.sigNum()>0) {
720
+ r = (a+z.intValue()).toString(b).substr(1) + r;
721
+ y.divRemTo(d,y,z);
722
+ }
723
+ return z.intValue().toString(b) + r;
724
+ }
725
+
726
+ /**
727
+ *
728
+ * @param s a string to convert from using radix.
729
+ * @param b a radix
730
+ *
731
+ */
732
+ protected function fromRadix(s:String, b:int = 10):void {
733
+ fromInt(0);
734
+ var cs:int = chunkSize(b);
735
+ var d:Number = Math.pow(b, cs);
736
+ var mi:Boolean = false;
737
+ var j:int = 0;
738
+ var w:int = 0;
739
+ for (var i:int=0;i<s.length;++i) {
740
+ var x:int = intAt(s, i);
741
+ if (x<0) {
742
+ if (s.charAt(i) == "-" && sigNum() == 0) {
743
+ mi = true;
744
+ }
745
+ continue;
746
+ }
747
+ w = b*w+x;
748
+ if (++j >= cs) {
749
+ dMultiply(d);
750
+ dAddOffset(w,0);
751
+ j=0;
752
+ w=0;
753
+ }
754
+ }
755
+ if (j>0) {
756
+ dMultiply(Math.pow(b,j));
757
+ dAddOffset(w,0);
758
+ }
759
+ if (mi) {
760
+ BigInteger.ZERO.subTo(this, this);
761
+ }
762
+ }
763
+
764
+ // XXX function fromNumber not written yet.
765
+
766
+ /**
767
+ *
768
+ * @return a byte array.
769
+ *
770
+ */
771
+ public function toByteArray():ByteArray {
772
+ var i:int = t;
773
+ var r:ByteArray = new ByteArray;
774
+ r[0] = s;
775
+ var p:int = DB-(i*DB)%8;
776
+ var d:int;
777
+ var k:int=0;
778
+ if (i-->0) {
779
+ if (p<DB && (d=a[i]>>p)!=(s&DM)>>p) {
780
+ r[k++] = d|(s<<(DB-p));
781
+ }
782
+ while (i>=0) {
783
+ if(p<8) {
784
+ d = (a[i]&((1<<p)-1))<<(8-p);
785
+ d|= a[--i]>>(p+=DB-8);
786
+ } else {
787
+ d = (a[i]>>(p-=8))&0xff;
788
+ if (p<=0) {
789
+ p += DB;
790
+ --i;
791
+ }
792
+ }
793
+ if ((d&0x80)!=0) d|=-256;
794
+ if (k==0 && (s&0x80)!=(d&0x80)) ++k;
795
+ if (k>0 || d!=s) r[k++] = d;
796
+ }
797
+ }
798
+ return r;
799
+ }
800
+
801
+ public function equals(a:BigInteger):Boolean {
802
+ return compareTo(a)==0;
803
+ }
804
+ public function min(a:BigInteger):BigInteger {
805
+ return (compareTo(a)<0)?this:a;
806
+ }
807
+ public function max(a:BigInteger):BigInteger {
808
+ return (compareTo(a)>0)?this:a;
809
+ }
810
+
811
+ /**
812
+ *
813
+ * @param a a BigInteger to perform the operation with
814
+ * @param op a Function implementing the operation
815
+ * @param r a BigInteger to store the result of the operation
816
+ *
817
+ */
818
+ protected function bitwiseTo(a:BigInteger, op:Function, r:BigInteger):void {
819
+ var i:int;
820
+ var f:int;
821
+ var m:int = Math.min(a.t, t);
822
+ for (i=0; i<m; ++i) {
823
+ r.a[i] = op(this.a[i],a.a[i]);
824
+ }
825
+ if (a.t<t) {
826
+ f = a.s&DM;
827
+ for (i=m;i<t;++i) {
828
+ r.a[i] = op(this.a[i],f);
829
+ }
830
+ r.t = t;
831
+ } else {
832
+ f = s&DM;
833
+ for (i=m;i<a.t;++i) {
834
+ r.a[i] = op(f,a.a[i]);
835
+ }
836
+ r.t = a.t;
837
+ }
838
+ r.s = op(s, a.s);
839
+ r.clamp();
840
+ }
841
+
842
+ private function op_and(x:int, y:int):int {return x&y;}
843
+ public function and(a:BigInteger):BigInteger {
844
+ var r:BigInteger = new BigInteger;
845
+ bitwiseTo(a, op_and, r);
846
+ return r;
847
+ }
848
+
849
+ private function op_or(x:int, y:int):int {return x|y;}
850
+ public function or(a:BigInteger):BigInteger {
851
+ var r:BigInteger = new BigInteger;
852
+ bitwiseTo(a, op_or, r);
853
+ return r;
854
+ }
855
+
856
+ private function op_xor(x:int, y:int):int {return x^y;}
857
+ public function xor(a:BigInteger):BigInteger {
858
+ var r:BigInteger = new BigInteger;
859
+ bitwiseTo(a, op_xor, r);
860
+ return r;
861
+ }
862
+
863
+ private function op_andnot(x:int, y:int):int { return x&~y;}
864
+ public function andNot(a:BigInteger):BigInteger {
865
+ var r:BigInteger = new BigInteger;
866
+ bitwiseTo(a, op_andnot, r);
867
+ return r;
868
+ }
869
+
870
+ public function not():BigInteger {
871
+ var r:BigInteger = new BigInteger;
872
+ for (var i:int=0;i<t;++i) {
873
+ r[i] = DM&~a[i];
874
+ }
875
+ r.t = t;
876
+ r.s = ~s;
877
+ return r;
878
+ }
879
+
880
+ public function shiftLeft(n:int):BigInteger {
881
+ var r:BigInteger = new BigInteger;
882
+ if (n<0) {
883
+ rShiftTo(-n, r);
884
+ } else {
885
+ lShiftTo(n, r);
886
+ }
887
+ return r;
888
+ }
889
+ public function shiftRight(n:int):BigInteger {
890
+ var r:BigInteger = new BigInteger;
891
+ if (n<0) {
892
+ lShiftTo(-n, r);
893
+ } else {
894
+ rShiftTo(n, r);
895
+ }
896
+ return r;
897
+ }
898
+
899
+ /**
900
+ *
901
+ * @param x
902
+ * @return index of lowet 1-bit in x, x < 2^31
903
+ *
904
+ */
905
+ private function lbit(x:int):int {
906
+ if (x==0) return -1;
907
+ var r:int = 0;
908
+ if ((x&0xffff)==0) { x>>= 16; r += 16; }
909
+ if ((x&0xff) == 0) { x>>= 8; r += 8; }
910
+ if ((x&0xf) == 0) { x>>= 4; r += 4; }
911
+ if ((x&0x3) == 0) { x>>= 2; r += 2; }
912
+ if ((x&0x1) == 0) ++r;
913
+ return r;
914
+ }
915
+
916
+ /**
917
+ *
918
+ * @return index of lowest 1-bit (or -1 if none)
919
+ *
920
+ */
921
+ public function getLowestSetBit():int {
922
+ for (var i:int=0;i<t;++i) {
923
+ if (a[i]!=0) return i*DB+lbit(a[i]);
924
+ }
925
+ if (s<0) return t*DB;
926
+ return -1;
927
+ }
928
+
929
+ /**
930
+ *
931
+ * @param x
932
+ * @return number of 1 bits in x
933
+ *
934
+ */
935
+ private function cbit(x:int):int {
936
+ var r:uint =0;
937
+ while (x!=0) { x &= x-1; ++r }
938
+ return r;
939
+ }
940
+
941
+ /**
942
+ *
943
+ * @return number of set bits
944
+ *
945
+ */
946
+ public function bitCount():int {
947
+ var r:int=0;
948
+ var x:int = s&DM;
949
+ for (var i:int=0;i<t;++i) {
950
+ r += cbit(a[i]^x);
951
+ }
952
+ return r;
953
+ }
954
+
955
+ /**
956
+ *
957
+ * @param n
958
+ * @return true iff nth bit is set
959
+ *
960
+ */
961
+ public function testBit(n:int):Boolean {
962
+ var j:int = Math.floor(n/DB);
963
+ if (j>=t) {
964
+ return s!=0;
965
+ }
966
+ return ((a[j]&(1<<(n%DB)))!=0);
967
+ }
968
+
969
+ /**
970
+ *
971
+ * @param n
972
+ * @param op
973
+ * @return this op (1<<n)
974
+ *
975
+ */
976
+ protected function changeBit(n:int,op:Function):BigInteger {
977
+ var r:BigInteger = BigInteger.ONE.shiftLeft(n);
978
+ bitwiseTo(r, op, r);
979
+ return r;
980
+ }
981
+
982
+ /**
983
+ *
984
+ * @param n
985
+ * @return this | (1<<n)
986
+ *
987
+ */
988
+ public function setBit(n:int):BigInteger { return changeBit(n, op_or); }
989
+
990
+ /**
991
+ *
992
+ * @param n
993
+ * @return this & ~(1<<n)
994
+ *
995
+ */
996
+ public function clearBit(n:int):BigInteger { return changeBit(n, op_andnot); }
997
+
998
+ /**
999
+ *
1000
+ * @param n
1001
+ * @return this ^ (1<<n)
1002
+ *
1003
+ */
1004
+ public function flipBit(n:int):BigInteger { return changeBit(n, op_xor); }
1005
+
1006
+ /**
1007
+ *
1008
+ * @param a
1009
+ * @param r = this + a
1010
+ *
1011
+ */
1012
+ protected function addTo(a:BigInteger, r:BigInteger):void {
1013
+ var i:int = 0;
1014
+ var c:int = 0;
1015
+ var m:int = Math.min(a.t, t);
1016
+ while (i<m) {
1017
+ c += this.a[i] + a.a[i];
1018
+ r.a[i++] = c&DM;
1019
+ c>>=DB;
1020
+ }
1021
+ if (a.t < t) {
1022
+ c += a.s;
1023
+ while (i<t) {
1024
+ c += this.a[i];
1025
+ r.a[i++] = c&DM;
1026
+ c >>= DB;
1027
+ }
1028
+ c += s;
1029
+ } else {
1030
+ c += s;
1031
+ while (i<a.t) {
1032
+ c += a.a[i];
1033
+ r.a[i++] = c&DM;
1034
+ c >>= DB;
1035
+ }
1036
+ c += a.s;
1037
+ }
1038
+ r.s = (c<0)?-1:0;
1039
+ if (c>0) {
1040
+ r.a[i++] = c;
1041
+ } else if (c<-1) {
1042
+ r.a[i++] = DV+c;
1043
+ }
1044
+ r.t = i;
1045
+ r.clamp();
1046
+ }
1047
+
1048
+ /**
1049
+ *
1050
+ * @param a
1051
+ * @return this + a
1052
+ *
1053
+ */
1054
+ public function add(a:BigInteger):BigInteger {
1055
+ var r:BigInteger = new BigInteger;
1056
+ addTo(a,r);
1057
+ return r;
1058
+ }
1059
+
1060
+ /**
1061
+ *
1062
+ * @param a
1063
+ * @return this - a
1064
+ *
1065
+ */
1066
+ public function subtract(a:BigInteger):BigInteger {
1067
+ var r:BigInteger = new BigInteger;
1068
+ subTo(a,r);
1069
+ return r;
1070
+ }
1071
+
1072
+ /**
1073
+ *
1074
+ * @param a
1075
+ * @return this * a
1076
+ *
1077
+ */
1078
+ public function multiply(a:BigInteger):BigInteger {
1079
+ var r:BigInteger = new BigInteger;
1080
+ multiplyTo(a,r);
1081
+ return r;
1082
+ }
1083
+
1084
+ /**
1085
+ *
1086
+ * @param a
1087
+ * @return this / a
1088
+ *
1089
+ */
1090
+ public function divide(a:BigInteger):BigInteger {
1091
+ var r:BigInteger = new BigInteger;
1092
+ divRemTo(a, r, null);
1093
+ return r;
1094
+ }
1095
+
1096
+ public function remainder(a:BigInteger):BigInteger {
1097
+ var r:BigInteger = new BigInteger;
1098
+ divRemTo(a, null, r);
1099
+ return r;
1100
+ }
1101
+
1102
+ /**
1103
+ *
1104
+ * @param a
1105
+ * @return [this/a, this%a]
1106
+ *
1107
+ */
1108
+ public function divideAndRemainder(a:BigInteger):Array {
1109
+ var q:BigInteger = new BigInteger;
1110
+ var r:BigInteger = new BigInteger;
1111
+ divRemTo(a, q, r);
1112
+ return [q,r];
1113
+ }
1114
+
1115
+ /**
1116
+ *
1117
+ * this *= n, this >=0, 1 < n < DV
1118
+ *
1119
+ * @param n
1120
+ *
1121
+ */
1122
+ bi_internal function dMultiply(n:int):void {
1123
+ a[t] = am(0, n-1, this, 0, 0, t);
1124
+ ++t;
1125
+ clamp();
1126
+ }
1127
+
1128
+ /**
1129
+ *
1130
+ * this += n << w words, this >= 0
1131
+ *
1132
+ * @param n
1133
+ * @param w
1134
+ *
1135
+ */
1136
+ bi_internal function dAddOffset(n:int, w:int):void {
1137
+ while (t<=w) {
1138
+ a[t++] = 0;
1139
+ }
1140
+ a[w] += n;
1141
+ while (a[w] >= DV) {
1142
+ a[w] -= DV;
1143
+ if (++w >= t) {
1144
+ a[t++] = 0;
1145
+ }
1146
+ ++a[w];
1147
+ }
1148
+ }
1149
+
1150
+ /**
1151
+ *
1152
+ * @param e
1153
+ * @return this^e
1154
+ *
1155
+ */
1156
+ public function pow(e:int):BigInteger {
1157
+ return exp(e, new NullReduction);
1158
+ }
1159
+
1160
+ /**
1161
+ *
1162
+ * @param a
1163
+ * @param n
1164
+ * @param r = lower n words of "this * a", a.t <= n
1165
+ *
1166
+ */
1167
+ bi_internal function multiplyLowerTo(a:BigInteger, n:int, r:BigInteger):void {
1168
+ var i:int = Math.min(t+a.t, n);
1169
+ r.s = 0; // assumes a, this >= 0
1170
+ r.t = i;
1171
+ while (i>0) {
1172
+ r.a[--i]=0;
1173
+ }
1174
+ var j:int;
1175
+ for (j=r.t-t;i<j;++i) {
1176
+ r.a[i+t] = am(0, a.a[i], r, i, 0, t);
1177
+ }
1178
+ for (j=Math.min(a.t,n);i<j;++i) {
1179
+ am(0, a.a[i], r, i, 0, n-i);
1180
+ }
1181
+ r.clamp();
1182
+ }
1183
+
1184
+ /**
1185
+ *
1186
+ * @param a
1187
+ * @param n
1188
+ * @param r = "this * a" without lower n words, n > 0
1189
+ *
1190
+ */
1191
+ bi_internal function multiplyUpperTo(a:BigInteger, n:int, r:BigInteger):void {
1192
+ --n;
1193
+ var i:int = r.t = t+a.t-n;
1194
+ r.s = 0; // assumes a,this >= 0
1195
+ while (--i>=0) {
1196
+ r.a[i] = 0;
1197
+ }
1198
+ for (i=Math.max(n-t,0);i<a.t;++i) {
1199
+ r.a[t+i-n] = am(n-i, a.a[i], r, 0, 0, t+i-n);
1200
+ }
1201
+ r.clamp();
1202
+ r.drShiftTo(1,r);
1203
+ }
1204
+
1205
+ /**
1206
+ *
1207
+ * @param e
1208
+ * @param m
1209
+ * @return this^e % m (HAC 14.85)
1210
+ *
1211
+ */
1212
+ public function modPow(e:BigInteger, m:BigInteger):BigInteger {
1213
+ var i:int = e.bitLength();
1214
+ var k:int;
1215
+ var r:BigInteger = nbv(1);
1216
+ var z:IReduction;
1217
+
1218
+ if (i<=0) {
1219
+ return r;
1220
+ } else if (i<18) {
1221
+ k=1;
1222
+ } else if (i<48) {
1223
+ k=3;
1224
+ } else if (i<144) {
1225
+ k=4;
1226
+ } else if (i<768) {
1227
+ k=5;
1228
+ } else {
1229
+ k=6;
1230
+ }
1231
+ if (i<8) {
1232
+ z = new ClassicReduction(m);
1233
+ } else if (m.isEven()) {
1234
+ z = new BarrettReduction(m);
1235
+ } else {
1236
+ z = new MontgomeryReduction(m);
1237
+ }
1238
+ // precomputation
1239
+ var g:Array = [];
1240
+ var n:int = 3;
1241
+ var k1:int = k-1;
1242
+ var km:int = (1<<k)-1;
1243
+ g[1] = z.convert(this);
1244
+ if (k > 1) {
1245
+ var g2:BigInteger = new BigInteger;
1246
+ z.sqrTo(g[1], g2);
1247
+ while (n<=km) {
1248
+ g[n] = new BigInteger;
1249
+ z.mulTo(g2, g[n-2], g[n]);
1250
+ n += 2;
1251
+ }
1252
+ }
1253
+
1254
+ var j:int = e.t-1;
1255
+ var w:int;
1256
+ var is1:Boolean = true;
1257
+ var r2:BigInteger = new BigInteger;
1258
+ var t:BigInteger;
1259
+ i = nbits(e.a[j])-1;
1260
+ while (j>=0) {
1261
+ if (i>=k1) {
1262
+ w = (e.a[j]>>(i-k1))&km;
1263
+ } else {
1264
+ w = (e.a[j]&((1<<(i+1))-1))<<(k1-i);
1265
+ if (j>0) {
1266
+ w |= e.a[j-1]>>(DB+i-k1);
1267
+ }
1268
+ }
1269
+ n = k;
1270
+ while ((w&1)==0) {
1271
+ w >>= 1;
1272
+ --n;
1273
+ }
1274
+ if ((i -= n) <0) {
1275
+ i += DB;
1276
+ --j;
1277
+ }
1278
+ if (is1) { // ret == 1, don't bother squaring or multiplying it
1279
+ g[w].copyTo(r);
1280
+ is1 = false;
1281
+ } else {
1282
+ while (n>1) {
1283
+ z.sqrTo(r, r2);
1284
+ z.sqrTo(r2, r);
1285
+ n -= 2;
1286
+ }
1287
+ if (n>0) {
1288
+ z.sqrTo(r, r2);
1289
+ } else {
1290
+ t = r;
1291
+ r = r2;
1292
+ r2 = t;
1293
+ }
1294
+ z.mulTo(r2, g[w], r);
1295
+ }
1296
+ while (j>=0 && (e.a[j]&(1<<i)) == 0) {
1297
+ z.sqrTo(r, r2);
1298
+ t = r;
1299
+ r = r2;
1300
+ r2 = t;
1301
+ if (--i<0) {
1302
+ i = DB-1;
1303
+ --j;
1304
+ }
1305
+
1306
+ }
1307
+ }
1308
+ return z.revert(r);
1309
+ }
1310
+
1311
+ /**
1312
+ *
1313
+ * @param a
1314
+ * @return gcd(this, a) (HAC 14.54)
1315
+ *
1316
+ */
1317
+ public function gcd(a:BigInteger):BigInteger {
1318
+ var x:BigInteger = (s<0)?negate():clone();
1319
+ var y:BigInteger = (a.s<0)?a.negate():a.clone();
1320
+ if (x.compareTo(y)<0) {
1321
+ var t:BigInteger=x;
1322
+ x=y;
1323
+ y=t;
1324
+ }
1325
+ var i:int = x.getLowestSetBit();
1326
+ var g:int = y.getLowestSetBit();
1327
+ if (g<0) return x;
1328
+ if (i<g) g= i;
1329
+ if (g>0) {
1330
+ x.rShiftTo(g, x);
1331
+ y.rShiftTo(g, y);
1332
+ }
1333
+ while (x.sigNum()>0) {
1334
+ if ((i = x.getLowestSetBit()) >0) {
1335
+ x.rShiftTo(i, x);
1336
+ }
1337
+ if ((i = y.getLowestSetBit()) >0) {
1338
+ y.rShiftTo(i, y);
1339
+ }
1340
+ if (x.compareTo(y) >= 0) {
1341
+ x.subTo(y, x);
1342
+ x.rShiftTo(1, x);
1343
+ } else {
1344
+ y.subTo(x, y);
1345
+ y.rShiftTo(1, y);
1346
+ }
1347
+ }
1348
+ if (g>0) {
1349
+ y.lShiftTo(g, y);
1350
+ }
1351
+ return y;
1352
+ }
1353
+
1354
+ /**
1355
+ *
1356
+ * @param n
1357
+ * @return this % n, n < 2^DB
1358
+ *
1359
+ */
1360
+ protected function modInt(n:int):int {
1361
+ if (n<=0) return 0;
1362
+ var d:int = DV%n;
1363
+ var r:int = (s<0)?n-1:0;
1364
+ if (t>0) {
1365
+ if (d==0) {
1366
+ r = a[0]%n;
1367
+ } else {
1368
+ for (var i:int=t-1;i>=0;--i) {
1369
+ r = (d*r+a[i])%n;
1370
+ }
1371
+ }
1372
+ }
1373
+ return r;
1374
+ }
1375
+
1376
+ /**
1377
+ *
1378
+ * @param m
1379
+ * @return 1/this %m (HAC 14.61)
1380
+ *
1381
+ */
1382
+ public function modInverse(m:BigInteger):BigInteger {
1383
+ var ac:Boolean = m.isEven();
1384
+ if ((isEven()&&ac) || m.sigNum()==0) {
1385
+ return BigInteger.ZERO;
1386
+ }
1387
+ var u:BigInteger = m.clone();
1388
+ var v:BigInteger = clone();
1389
+ var a:BigInteger = nbv(1);
1390
+ var b:BigInteger = nbv(0);
1391
+ var c:BigInteger = nbv(0);
1392
+ var d:BigInteger = nbv(1);
1393
+ while (u.sigNum()!=0) {
1394
+ while (u.isEven()) {
1395
+ u.rShiftTo(1,u);
1396
+ if (ac) {
1397
+ if (!a.isEven() || !b.isEven()) {
1398
+ a.addTo(this,a);
1399
+ b.subTo(m,b);
1400
+ }
1401
+ a.rShiftTo(1,a);
1402
+ } else if (!b.isEven()) {
1403
+ b.subTo(m,b);
1404
+ }
1405
+ b.rShiftTo(1,b);
1406
+ }
1407
+ while (v.isEven()) {
1408
+ v.rShiftTo(1,v);
1409
+ if (ac) {
1410
+ if (!c.isEven() || !d.isEven()) {
1411
+ c.addTo(this,c);
1412
+ d.subTo(m,d);
1413
+ }
1414
+ c.rShiftTo(1,c);
1415
+ } else if (!d.isEven()) {
1416
+ d.subTo(m,d);
1417
+ }
1418
+ d.rShiftTo(1,d);
1419
+ }
1420
+ if (u.compareTo(v)>=0) {
1421
+ u.subTo(v,u);
1422
+ if (ac) {
1423
+ a.subTo(c,a);
1424
+ }
1425
+ b.subTo(d,b);
1426
+ } else {
1427
+ v.subTo(u,v);
1428
+ if (ac) {
1429
+ c.subTo(a,c);
1430
+ }
1431
+ d.subTo(b,d);
1432
+ }
1433
+ }
1434
+ if (v.compareTo(BigInteger.ONE) != 0) {
1435
+ return BigInteger.ZERO;
1436
+ }
1437
+ if (d.compareTo(m) >= 0) {
1438
+ return d.subtract(m);
1439
+ }
1440
+ if (d.sigNum()<0) {
1441
+ d.addTo(m,d);
1442
+ } else {
1443
+ return d;
1444
+ }
1445
+ if (d.sigNum()<0) {
1446
+ return d.add(m);
1447
+ } else {
1448
+ return d;
1449
+ }
1450
+ }
1451
+
1452
+ /**
1453
+ *
1454
+ * @param t
1455
+ * @return primality with certainty >= 1-.5^t
1456
+ *
1457
+ */
1458
+ public function isProbablePrime(t:int):Boolean {
1459
+ var i:int;
1460
+ var x:BigInteger = abs();
1461
+ if (x.t == 1 && x.a[0]<=lowprimes[lowprimes.length-1]) {
1462
+ for (i=0;i<lowprimes.length;++i) {
1463
+ if (x[0]==lowprimes[i]) return true;
1464
+ }
1465
+ return false;
1466
+ }
1467
+ if (x.isEven()) return false;
1468
+ i = 1;
1469
+ while (i<lowprimes.length) {
1470
+ var m:int = lowprimes[i];
1471
+ var j:int = i+1;
1472
+ while (j<lowprimes.length && m<lplim) {
1473
+ m *= lowprimes[j++];
1474
+ }
1475
+ m = x.modInt(m);
1476
+ while (i<j) {
1477
+ if (m%lowprimes[i++]==0) {
1478
+ return false;
1479
+ }
1480
+ }
1481
+ }
1482
+ return x.millerRabin(t);
1483
+ }
1484
+
1485
+ /**
1486
+ *
1487
+ * @param t
1488
+ * @return true if probably prime (HAC 4.24, Miller-Rabin)
1489
+ *
1490
+ */
1491
+ protected function millerRabin(t:int):Boolean {
1492
+ var n1:BigInteger = subtract(BigInteger.ONE);
1493
+ var k:int = n1.getLowestSetBit();
1494
+ if (k<=0) {
1495
+ return false;
1496
+ }
1497
+ var r:BigInteger = n1.shiftRight(k);
1498
+ t = (t+1)>>1;
1499
+ if (t>lowprimes.length) {
1500
+ t = lowprimes.length;
1501
+ }
1502
+ var a:BigInteger = new BigInteger;
1503
+ for (var i:int=0;i<t;++i) {
1504
+ a.fromInt(lowprimes[i]);
1505
+ var y:BigInteger = a.modPow(r, this);
1506
+ if (y.compareTo(BigInteger.ONE)!=0 && y.compareTo(n1)!=0) {
1507
+ var j:int = 1;
1508
+ while (j++<k && y.compareTo(n1)!=0) {
1509
+ y = y.modPowInt(2, this);
1510
+ if (y.compareTo(BigInteger.ONE)==0) {
1511
+ return false;
1512
+ }
1513
+ }
1514
+ if (y.compareTo(n1)!=0) {
1515
+ return false;
1516
+ }
1517
+ }
1518
+ }
1519
+ return true;
1520
+ }
1521
+
1522
+ /**
1523
+ * Tweak our BigInteger until it looks prime enough
1524
+ *
1525
+ * @param bits
1526
+ * @param t
1527
+ *
1528
+ */
1529
+ public function primify(bits:int, t:int):void {
1530
+ if (!testBit(bits-1)) { // force MSB set
1531
+ bitwiseTo(BigInteger.ONE.shiftLeft(bits-1), op_or, this);
1532
+ }
1533
+ if (isEven()) {
1534
+ dAddOffset(1,0); // force odd
1535
+ }
1536
+ while (!isProbablePrime(t)) {
1537
+ dAddOffset(2,0);
1538
+ while(bitLength()>bits) subTo(BigInteger.ONE.shiftLeft(bits-1),this);
1539
+ }
1540
+ }
1541
+
1542
+ }
1543
+ }