Diffstat (limited to 'frontend/beta/js/Clipperz/Crypto/ECC.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/Clipperz/Crypto/ECC.js | 960 |
1 files changed, 960 insertions, 0 deletions
diff --git a/frontend/beta/js/Clipperz/Crypto/ECC.js b/frontend/beta/js/Clipperz/Crypto/ECC.js new file mode 100644 index 0000000..c3dcec3 --- a/dev/null +++ b/frontend/beta/js/Clipperz/Crypto/ECC.js | |||
@@ -0,0 +1,960 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz's Javascript Crypto Library. | ||
6 | Javascript Crypto Library provides web developers with an extensive | ||
7 | and efficient set of cryptographic functions. The library aims to | ||
8 | obtain maximum execution speed while preserving modularity and | ||
9 | reusability. | ||
10 | For further information about its features and functionalities please | ||
11 | refer to http://www.clipperz.com | ||
12 | |||
13 | * Javascript Crypto Library is free software: you can redistribute | ||
14 | it and/or modify it under the terms of the GNU Affero General Public | ||
15 | License as published by the Free Software Foundation, either version | ||
16 | 3 of the License, or (at your option) any later version. | ||
17 | |||
18 | * Javascript Crypto Library is distributed in the hope that it will | ||
19 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | See the GNU Affero General Public License for more details. | ||
22 | |||
23 | * You should have received a copy of the GNU Affero General Public | ||
24 | License along with Javascript Crypto Library. If not, see | ||
25 | <http://www.gnu.org/licenses/>. | ||
26 | |||
27 | */ | ||
28 | |||
29 | /* | ||
30 | try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { | ||
31 | throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!"; | ||
32 | } | ||
33 | |||
34 | if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; } | ||
35 | |||
36 | |||
37 | //############################################################################# | ||
38 | |||
39 | Clipperz.Crypto.ECC.BinaryField = {}; | ||
40 | |||
41 | //############################################################################# | ||
42 | |||
43 | Clipperz.Crypto.ECC.BinaryField.AbstractValue = function(aValue, aBase) { | ||
44 | return this; | ||
45 | } | ||
46 | |||
47 | Clipperz.Crypto.ECC.BinaryField.AbstractValue.prototype = MochiKit.Base.update(null, { | ||
48 | |||
49 | 'asString': function(aBase) { | ||
50 | throw Clipperz.Base.exception.AbstractMethod; | ||
51 | }, | ||
52 | |||
53 | 'isZero': function() { | ||
54 | throw Clipperz.Base.exception.AbstractMethod; | ||
55 | }, | ||
56 | |||
57 | 'shiftLeft': function(aNumberOfBitsToShift) { | ||
58 | throw Clipperz.Base.exception.AbstractMethod; | ||
59 | }, | ||
60 | |||
61 | 'bitSize': function() { | ||
62 | throw Clipperz.Base.exception.AbstractMethod; | ||
63 | }, | ||
64 | |||
65 | 'isBitSet': function(aBitPosition) { | ||
66 | throw Clipperz.Base.exception.AbstractMethod; | ||
67 | }, | ||
68 | |||
69 | 'xor': function(aValue) { | ||
70 | throw Clipperz.Base.exception.AbstractMethod; | ||
71 | }, | ||
72 | |||
73 | 'compare': function(aValue) { | ||
74 | throw Clipperz.Base.exception.AbstractMethod; | ||
75 | }, | ||
76 | |||
77 | //----------------------------------------------------------------------------- | ||
78 | __syntaxFix__: "syntax fix" | ||
79 | }); | ||
80 | |||
81 | //***************************************************************************** | ||
82 | / * | ||
83 | Clipperz.Crypto.ECC.BinaryField.BigIntValue = function(aValue, aBase) { | ||
84 | this._value = new Clipperz.Crypto.BigInt(aValue, aBase); | ||
85 | return this; | ||
86 | } | ||
87 | |||
88 | Clipperz.Crypto.ECC.BinaryField.BigIntValue.prototype = MochiKit.Base.update(new Clipperz.Crypto.ECC.BinaryField.AbstractValue(), { | ||
89 | |||
90 | 'value': function() { | ||
91 | return this._value; | ||
92 | }, | ||
93 | |||
94 | //----------------------------------------------------------------------------- | ||
95 | |||
96 | 'isZero': function() { | ||
97 | return (this.value().compare(Clipperz.Crypto.ECC.BinaryField.BigIntValue.O) == 0); | ||
98 | }, | ||
99 | |||
100 | //----------------------------------------------------------------------------- | ||
101 | |||
102 | 'asString': function(aBase) { | ||
103 | return this.value().asString(aBase); | ||
104 | }, | ||
105 | |||
106 | //----------------------------------------------------------------------------- | ||
107 | |||
108 | 'shiftLeft': function(aNumberOfBitsToShift) { | ||
109 | return new Clipperz.Crypto.ECC.BinaryField.BigIntValue(this.value().shiftLeft(aNumberOfBitsToShift)); | ||
110 | }, | ||
111 | |||
112 | //----------------------------------------------------------------------------- | ||
113 | |||
114 | 'bitSize': function() { | ||
115 | return this.value().bitSize(); | ||
116 | }, | ||
117 | |||
118 | //----------------------------------------------------------------------------- | ||
119 | |||
120 | 'isBitSet': function(aBitPosition) { | ||
121 | return this.value().isBitSet(aBitPosition); | ||
122 | }, | ||
123 | |||
124 | //----------------------------------------------------------------------------- | ||
125 | |||
126 | 'xor': function(aValue) { | ||
127 | return new Clipperz.Crypto.ECC.BinaryField.BigIntValue(this.value().xor(aValue.value())); | ||
128 | }, | ||
129 | |||
130 | //----------------------------------------------------------------------------- | ||
131 | |||
132 | 'compare': function(aValue) { | ||
133 | return this.value().compare(aValue.value()); | ||
134 | }, | ||
135 | |||
136 | //----------------------------------------------------------------------------- | ||
137 | __syntaxFix__: "syntax fix" | ||
138 | }); | ||
139 | |||
140 | Clipperz.Crypto.ECC.BinaryField.BigIntValue.O = new Clipperz.Crypto.BigInt(0); | ||
141 | Clipperz.Crypto.ECC.BinaryField.BigIntValue.I = new Clipperz.Crypto.BigInt(1); | ||
142 | * / | ||
143 | //***************************************************************************** | ||
144 | |||
145 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue = function(aValue, aBase) { | ||
146 | if (aValue.constructor == String) { | ||
147 | varvalue; | ||
148 | varstringLength; | ||
149 | var numberOfWords; | ||
150 | vari,c; | ||
151 | |||
152 | if (aBase != 16) { | ||
153 | throw Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedBase; | ||
154 | } | ||
155 | |||
156 | value = aValue.replace(/ /g, ''); | ||
157 | stringLength = value.length; | ||
158 | numberOfWords = Math.ceil(stringLength / 8); | ||
159 | this._value = new Array(numberOfWords); | ||
160 | |||
161 | c = numberOfWords; | ||
162 | for (i=0; i<c; i++) { | ||
163 | varword; | ||
164 | |||
165 | if (i < (c-1)) { | ||
166 | word = parseInt(value.substr(stringLength-((i+1)*8), 8), 16); | ||
167 | } else { | ||
168 | word = parseInt(value.substr(0, stringLength-(i*8)), 16); | ||
169 | } | ||
170 | |||
171 | this._value[i] = word; | ||
172 | } | ||
173 | } else if (aValue.constructor == Array) { | ||
174 | var itemsToCopy; | ||
175 | |||
176 | itemsToCopy = aValue.length; | ||
177 | while (aValue[itemsToCopy - 1] == 0) { | ||
178 | itemsToCopy --; | ||
179 | } | ||
180 | |||
181 | this._value = aValue.slice(0, itemsToCopy); | ||
182 | } else if (aValue.constructor == Number) { | ||
183 | this._value = [aValue]; | ||
184 | } else { | ||
185 | // throw Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedConstructorValueType; | ||
186 | } | ||
187 | |||
188 | return this; | ||
189 | } | ||
190 | |||
191 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.prototype = MochiKit.Base.update(new Clipperz.Crypto.ECC.BinaryField.AbstractValue(), { | ||
192 | |||
193 | 'value': function() { | ||
194 | return this._value; | ||
195 | }, | ||
196 | |||
197 | //----------------------------------------------------------------------------- | ||
198 | |||
199 | 'wordSize': function() { | ||
200 | return this._value.length | ||
201 | }, | ||
202 | |||
203 | //----------------------------------------------------------------------------- | ||
204 | |||
205 | 'clone': function() { | ||
206 | return new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(this._value.slice(0)); | ||
207 | }, | ||
208 | |||
209 | //----------------------------------------------------------------------------- | ||
210 | |||
211 | 'isZero': function() { | ||
212 | return (this.compare(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.O) == 0); | ||
213 | }, | ||
214 | |||
215 | //----------------------------------------------------------------------------- | ||
216 | |||
217 | 'asString': function(aBase) { | ||
218 | varresult; | ||
219 | var i,c; | ||
220 | |||
221 | if (aBase != 16) { | ||
222 | throw Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedBase; | ||
223 | } | ||
224 | |||
225 | result = ""; | ||
226 | c = this.wordSize(); | ||
227 | for (i=0; i<c; i++) { | ||
228 | varwordAsString; | ||
229 | |||
230 | // wordAsString = ("00000000" + this.value()[i].toString(16)); | ||
231 | wordAsString = ("00000000" + this._value[i].toString(16)); | ||
232 | wordAsString = wordAsString.substring(wordAsString.length - 8); | ||
233 | result = wordAsString + result; | ||
234 | } | ||
235 | |||
236 | result = result.replace(/^(00)* SPACEs THAT SHOULD BE REMOVED TO FIX THIS REGEX /, ""); | ||
237 | |||
238 | if (result == "") { | ||
239 | result = "0"; | ||
240 | } | ||
241 | |||
242 | return result; | ||
243 | }, | ||
244 | |||
245 | //----------------------------------------------------------------------------- | ||
246 | |||
247 | 'shiftLeft': function(aNumberOfBitsToShift) { | ||
248 | return new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft(this._value, aNumberOfBitsToShift)); | ||
249 | }, | ||
250 | |||
251 | //----------------------------------------------------------------------------- | ||
252 | |||
253 | 'bitSize': function() { | ||
254 | return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(this._value); | ||
255 | }, | ||
256 | |||
257 | //----------------------------------------------------------------------------- | ||
258 | |||
259 | 'isBitSet': function(aBitPosition) { | ||
260 | return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.isBitSet(this._value, aBitPosition); | ||
261 | }, | ||
262 | |||
263 | //----------------------------------------------------------------------------- | ||
264 | |||
265 | 'xor': function(aValue) { | ||
266 | return new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(this._value, aValue._value)); | ||
267 | }, | ||
268 | |||
269 | //----------------------------------------------------------------------------- | ||
270 | |||
271 | 'compare': function(aValue) { | ||
272 | return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.compare(this._value, aValue._value); | ||
273 | }, | ||
274 | |||
275 | //----------------------------------------------------------------------------- | ||
276 | __syntaxFix__: "syntax fix" | ||
277 | }); | ||
278 | |||
279 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.O = new Clipperz.Crypto.ECC.BinaryField.WordArrayValue('0', 16); | ||
280 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.I = new Clipperz.Crypto.ECC.BinaryField.WordArrayValue('1', 16); | ||
281 | |||
282 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor = function(a, b) { | ||
283 | var result; | ||
284 | var resultSize; | ||
285 | var i,c; | ||
286 | |||
287 | resultSize = Math.max(a.length, b.length); | ||
288 | |||
289 | result = new Array(resultSize); | ||
290 | c = resultSize; | ||
291 | for (i=0; i<c; i++) { | ||
292 | // resultValue[i] = (((this.value()[i] || 0) ^ (aValue.value()[i] || 0)) >>> 0); | ||
293 | result[i] = (((a[i] || 0) ^ (b[i] || 0)) >>> 0); | ||
294 | } | ||
295 | |||
296 | return result; | ||
297 | }; | ||
298 | |||
299 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft = function(aWordArray, aNumberOfBitsToShift) { | ||
300 | var numberOfWordsToShift; | ||
301 | varnumberOfBitsToShift; | ||
302 | var result; | ||
303 | varoverflowValue; | ||
304 | vari,c; | ||
305 | |||
306 | numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32); | ||
307 | numberOfBitsToShift = aNumberOfBitsToShift % 32; | ||
308 | |||
309 | result = new Array(aWordArray.length + numberOfWordsToShift); | ||
310 | |||
311 | c = numberOfWordsToShift; | ||
312 | for (i=0; i<c; i++) { | ||
313 | result[i] = 0; | ||
314 | } | ||
315 | |||
316 | overflowValue = 0; | ||
317 | nextOverflowValue = 0; | ||
318 | |||
319 | c = aWordArray.length; | ||
320 | for (i=0; i<c; i++) { | ||
321 | varvalue; | ||
322 | varresultWord; | ||
323 | |||
324 | // value = this.value()[i]; | ||
325 | value = aWordArray[i]; | ||
326 | |||
327 | if (numberOfBitsToShift > 0) { | ||
328 | var nextOverflowValue; | ||
329 | |||
330 | nextOverflowValue = (value >>> (32 - numberOfBitsToShift)); | ||
331 | value = value & (0xffffffff >>> numberOfBitsToShift); | ||
332 | resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0); | ||
333 | } else { | ||
334 | resultWord = value; | ||
335 | } | ||
336 | |||
337 | result[i+numberOfWordsToShift] = resultWord; | ||
338 | overflowValue = nextOverflowValue; | ||
339 | } | ||
340 | |||
341 | if (overflowValue != 0) { | ||
342 | result[aWordArray.length + numberOfWordsToShift] = overflowValue; | ||
343 | } | ||
344 | |||
345 | return result; | ||
346 | }; | ||
347 | |||
348 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize = function(aWordArray) { | ||
349 | varresult; | ||
350 | varnotNullElements; | ||
351 | var mostValuableWord; | ||
352 | var matchingBitsInMostImportantWord; | ||
353 | var mask; | ||
354 | var i,c; | ||
355 | |||
356 | notNullElements = aWordArray.length; | ||
357 | |||
358 | if ((aWordArray.length == 1) && (aWordArray[0] == 0)) { | ||
359 | result = 0; | ||
360 | } else { | ||
361 | while((aWordArray[notNullElements - 1] == 0) && (notNullElements > 0)) { | ||
362 | notNullElements --; | ||
363 | } | ||
364 | |||
365 | result = (notNullElements - 1) * 32; | ||
366 | mostValuableWord = aWordArray[notNullElements - 1]; | ||
367 | |||
368 | matchingBits = 32; | ||
369 | mask = 0x80000000; | ||
370 | |||
371 | while ((matchingBits > 0) && ((mostValuableWord & mask) == 0)) { | ||
372 | matchingBits --; | ||
373 | mask >>>= 1; | ||
374 | } | ||
375 | |||
376 | result += matchingBits; | ||
377 | } | ||
378 | |||
379 | return result; | ||
380 | }; | ||
381 | |||
382 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.isBitSet = function(aWordArray, aBitPosition) { | ||
383 | var result; | ||
384 | varbyteIndex; | ||
385 | var bitIndexInSelectedByte; | ||
386 | |||
387 | byteIndex = Math.floor(aBitPosition / 32); | ||
388 | bitIndexInSelectedByte = aBitPosition % 32; | ||
389 | |||
390 | if (byteIndex <= aWordArray.length) { | ||
391 | result = ((aWordArray[byteIndex] & (1 << bitIndexInSelectedByte)) != 0); | ||
392 | } else { | ||
393 | result = false; | ||
394 | } | ||
395 | |||
396 | return result; | ||
397 | }; | ||
398 | |||
399 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue.compare = function(a,b) { | ||
400 | varresult; | ||
401 | var i,c; | ||
402 | |||
403 | result = MochiKit.Base.compare(a.length, b.length); | ||
404 | |||
405 | c = a.length; | ||
406 | for (i=0; (i<c) && (result==0); i++) { | ||
407 | //console.log("compare[" + c + " - " + i + " - 1] " + this.value()[c-i-1] + ", " + aValue.value()[c-i-1]); | ||
408 | // result = MochiKit.Base.compare(this.value()[c-i-1], aValue.value()[c-i-1]); | ||
409 | result = MochiKit.Base.compare(a[c-i-1], b[c-i-1]); | ||
410 | } | ||
411 | |||
412 | return result; | ||
413 | }; | ||
414 | |||
415 | |||
416 | Clipperz.Crypto.ECC.BinaryField.WordArrayValue['exception']= { | ||
417 | 'UnsupportedBase': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedBase"), | ||
418 | 'UnsupportedConstructorValueType':new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.WordArrayValue.exception.UnsupportedConstructorValueType") | ||
419 | }; | ||
420 | |||
421 | //***************************************************************************** | ||
422 | |||
423 | //Clipperz.Crypto.ECC.BinaryField.Value =Clipperz.Crypto.ECC.BinaryField.BigIntValue; | ||
424 | Clipperz.Crypto.ECC.BinaryField.Value =Clipperz.Crypto.ECC.BinaryField.WordArrayValue; | ||
425 | |||
426 | //############################################################################# | ||
427 | |||
428 | Clipperz.Crypto.ECC.BinaryField.Point = function(args) { | ||
429 | args = args || {}; | ||
430 | this._x = args.x; | ||
431 | this._y = args.y; | ||
432 | |||
433 | return this; | ||
434 | } | ||
435 | |||
436 | Clipperz.Crypto.ECC.BinaryField.Point.prototype = MochiKit.Base.update(null, { | ||
437 | |||
438 | 'asString': function() { | ||
439 | return "Clipperz.Crypto.ECC.BinaryField.Point (" + this.x() + ", " + this.y() + ")"; | ||
440 | }, | ||
441 | |||
442 | //----------------------------------------------------------------------------- | ||
443 | |||
444 | 'x': function() { | ||
445 | return this._x; | ||
446 | }, | ||
447 | |||
448 | 'y': function() { | ||
449 | return this._y; | ||
450 | }, | ||
451 | |||
452 | //----------------------------------------------------------------------------- | ||
453 | |||
454 | 'isZero': function() { | ||
455 | return (this.x().isZero() && this.y().isZero()) | ||
456 | }, | ||
457 | |||
458 | //----------------------------------------------------------------------------- | ||
459 | __syntaxFix__: "syntax fix" | ||
460 | }); | ||
461 | |||
462 | //############################################################################# | ||
463 | |||
464 | Clipperz.Crypto.ECC.BinaryField.FiniteField = function(args) { | ||
465 | args = args || {}; | ||
466 | this._modulus = args.modulus; | ||
467 | |||
468 | return this; | ||
469 | } | ||
470 | |||
471 | Clipperz.Crypto.ECC.BinaryField.FiniteField.prototype = MochiKit.Base.update(null, { | ||
472 | |||
473 | 'asString': function() { | ||
474 | return "Clipperz.Crypto.ECC.BinaryField.FiniteField (" + this.modulus().asString() + ")"; | ||
475 | }, | ||
476 | |||
477 | //----------------------------------------------------------------------------- | ||
478 | |||
479 | 'modulus': function() { | ||
480 | return this._modulus; | ||
481 | }, | ||
482 | |||
483 | //----------------------------------------------------------------------------- | ||
484 | |||
485 | '_module': function(aValue) { | ||
486 | varresult; | ||
487 | var modulusComparison; | ||
488 | //console.log(">>> binaryField.finiteField.(standard)module"); | ||
489 | |||
490 | modulusComparison = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.compare(aValue, this.modulus()._value); | ||
491 | |||
492 | if (modulusComparison < 0) { | ||
493 | result = aValue; | ||
494 | } else if (modulusComparison == 0) { | ||
495 | result = [0]; | ||
496 | } else { | ||
497 | var modulusBitSize; | ||
498 | var resultBitSize; | ||
499 | |||
500 | result = aValue; | ||
501 | |||
502 | modulusBitSize = this.modulus().bitSize(); | ||
503 | resultBitSize = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(result); | ||
504 | while (resultBitSize >= modulusBitSize) { | ||
505 | result = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(result, Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft(this.modulus()._value, resultBitSize - modulusBitSize)); | ||
506 | resultBitSize = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(result); | ||
507 | } | ||
508 | } | ||
509 | //console.log("<<< binaryField.finiteField.(standard)module"); | ||
510 | |||
511 | return result; | ||
512 | }, | ||
513 | |||
514 | 'module': function(aValue) { | ||
515 | return new Clipperz.Crypto.ECC.BinaryField.Value(this._module(aValue._value)); | ||
516 | }, | ||
517 | |||
518 | //----------------------------------------------------------------------------- | ||
519 | |||
520 | '_add': function(a, b) { | ||
521 | return Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(a, b); | ||
522 | }, | ||
523 | |||
524 | 'add': function(a, b) { | ||
525 | return new Clipperz.Crypto.ECC.BinaryField.Value(this._add(a._value, b._value)); | ||
526 | }, | ||
527 | |||
528 | //----------------------------------------------------------------------------- | ||
529 | |||
530 | 'negate': function(aValue) { | ||
531 | return aValue.clone(); | ||
532 | }, | ||
533 | |||
534 | //----------------------------------------------------------------------------- | ||
535 | / * | ||
536 | 'multiply': function(a, b) { | ||
537 | var result; | ||
538 | var valueToXor; | ||
539 | var i,c; | ||
540 | |||
541 | result = Clipperz.Crypto.ECC.BinaryField.Value.O; | ||
542 | valueToXor = b; | ||
543 | c = a.bitSize(); | ||
544 | for (i=0; i<c; i++) { | ||
545 | if (a.isBitSet(i) === true) { | ||
546 | result = result.xor(valueToXor); | ||
547 | } | ||
548 | valueToXor = valueToXor.shiftLeft(1); | ||
549 | } | ||
550 | result = this.module(result); | ||
551 | |||
552 | return result; | ||
553 | }, | ||
554 | * / | ||
555 | |||
556 | '_multiply': function(a, b) { | ||
557 | var result; | ||
558 | var valueToXor; | ||
559 | var i,c; | ||
560 | |||
561 | result = [0]; | ||
562 | valueToXor = b; | ||
563 | c = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.bitSize(a); | ||
564 | for (i=0; i<c; i++) { | ||
565 | if (Clipperz.Crypto.ECC.BinaryField.WordArrayValue.isBitSet(a, i) === true) { | ||
566 | result = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.xor(result, valueToXor); | ||
567 | } | ||
568 | valueToXor = Clipperz.Crypto.ECC.BinaryField.WordArrayValue.shiftLeft(valueToXor, 1); | ||
569 | } | ||
570 | result = this._module(result); | ||
571 | |||
572 | return result; | ||
573 | }, | ||
574 | |||
575 | 'multiply': function(a, b) { | ||
576 | return new Clipperz.Crypto.ECC.BinaryField.Value(this._multiply(a._value, b._value)); | ||
577 | }, | ||
578 | |||
579 | //----------------------------------------------------------------------------- | ||
580 | // | ||
581 | //Guide to Elliptic Curve Cryptography | ||
582 | //Darrel Hankerson, Alfred Menezes, Scott Vanstone | ||
583 | //- Pag: 49, Alorithm 2.34 | ||
584 | // | ||
585 | //----------------------------------------------------------------------------- | ||
586 | / * | ||
587 | 'square': function(aValue) { | ||
588 | varresult; | ||
589 | vart; | ||
590 | var i,c; | ||
591 | |||
592 | result = [0]; | ||
593 | t = Math.max(a) | ||
594 | c = 32; | ||
595 | for (i=0; i<c; i++) { | ||
596 | var ii, cc; | ||
597 | |||
598 | cc = | ||
599 | } | ||
600 | |||
601 | |||
602 | |||
603 | |||
604 | return result; | ||
605 | }, | ||
606 | * / | ||
607 | //----------------------------------------------------------------------------- | ||
608 | |||
609 | 'inverse': function(aValue) { | ||
610 | varresult; | ||
611 | var b, c; | ||
612 | var u, v; | ||
613 | |||
614 | b = Clipperz.Crypto.ECC.BinaryField.Value.I; | ||
615 | c = Clipperz.Crypto.ECC.BinaryField.Value.O; | ||
616 | u = this.module(aValue); | ||
617 | v = this.modulus(); | ||
618 | |||
619 | while (u.bitSize() > 1) { | ||
620 | varbitDifferenceSize; | ||
621 | |||
622 | bitDifferenceSize = u.bitSize() - v.bitSize(); | ||
623 | if (bitDifferenceSize < 0) { | ||
624 | var swap; | ||
625 | |||
626 | swap = u; | ||
627 | u = v; | ||
628 | v = swap; | ||
629 | |||
630 | swap = c; | ||
631 | c = b; | ||
632 | b = swap; | ||
633 | |||
634 | bitDifferenceSize = -bitDifferenceSize; | ||
635 | } | ||
636 | |||
637 | u = this.add(u, v.shiftLeft(bitDifferenceSize)); | ||
638 | b = this.add(b, c.shiftLeft(bitDifferenceSize)) | ||
639 | } | ||
640 | |||
641 | result = this.module(b); | ||
642 | |||
643 | return result; | ||
644 | }, | ||
645 | |||
646 | //----------------------------------------------------------------------------- | ||
647 | __syntaxFix__: "syntax fix" | ||
648 | }); | ||
649 | |||
650 | //############################################################################# | ||
651 | |||
652 | Clipperz.Crypto.ECC.BinaryField.Curve = function(args) { | ||
653 | args = args || {}; | ||
654 | |||
655 | this._modulus = args.modulus; | ||
656 | |||
657 | this._a = args.a; | ||
658 | this._b = args.b; | ||
659 | this._G = args.G; | ||
660 | this._r = args.r; | ||
661 | this._h = args.h; | ||
662 | |||
663 | this._finiteField = null; | ||
664 | |||
665 | return this; | ||
666 | } | ||
667 | |||
668 | Clipperz.Crypto.ECC.BinaryField.Curve.prototype = MochiKit.Base.update(null, { | ||
669 | |||
670 | 'asString': function() { | ||
671 | return "Clipperz.Crypto.ECC.BinaryField.Curve"; | ||
672 | }, | ||
673 | |||
674 | //----------------------------------------------------------------------------- | ||
675 | |||
676 | 'modulus': function() { | ||
677 | return this._modulus; | ||
678 | }, | ||
679 | |||
680 | 'a': function() { | ||
681 | return this._a; | ||
682 | }, | ||
683 | |||
684 | 'b': function() { | ||
685 | return this._b; | ||
686 | }, | ||
687 | |||
688 | 'G': function() { | ||
689 | return this._G; | ||
690 | }, | ||
691 | |||
692 | 'r': function() { | ||
693 | return this._r; | ||
694 | }, | ||
695 | |||
696 | 'h': function() { | ||
697 | return this._h; | ||
698 | }, | ||
699 | |||
700 | //----------------------------------------------------------------------------- | ||
701 | |||
702 | 'finiteField': function() { | ||
703 | if (this._finiteField == null) { | ||
704 | this._finiteField = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:this.modulus()}) | ||
705 | } | ||
706 | |||
707 | return this._finiteField; | ||
708 | }, | ||
709 | |||
710 | //----------------------------------------------------------------------------- | ||
711 | |||
712 | 'negate': function(aPointA) { | ||
713 | var result; | ||
714 | |||
715 | result = new Clipperz.Crypto.ECC.Point({x:aPointA.x(), y:this.finiteField().add(aPointA.y(), aPointA.x())}) | ||
716 | |||
717 | return result; | ||
718 | }, | ||
719 | |||
720 | //----------------------------------------------------------------------------- | ||
721 | |||
722 | 'add': function(aPointA, aPointB) { | ||
723 | var result; | ||
724 | |||
725 | //console.log(">>> ECC.BinaryField.Curve.add"); | ||
726 | if (aPointA.isZero()) { | ||
727 | //console.log("--- pointA == zero"); | ||
728 | result = aPointB; | ||
729 | } else if (aPointB.isZero()) { | ||
730 | //console.log("--- pointB == zero"); | ||
731 | result = aPointA; | ||
732 | } else if ((aPointA.x().compare(aPointB.x()) == 0) && | ||
733 | ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) | ||
734 | { | ||
735 | //console.log("compare A.x - B.x: ", aPointA.x().compare(aPointB.x())); | ||
736 | //console.log("compare A.y - B.y: ", (aPointA.y().compare(aPointB.y()) != 0)); | ||
737 | //console.log("compare B.x.isZero(): ", aPointB.x().isZero()); | ||
738 | |||
739 | //console.log("--- result = zero"); | ||
740 | result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O}); | ||
741 | } else { | ||
742 | //console.log("--- result = ELSE"); | ||
743 | varf2m; | ||
744 | var x, y; | ||
745 | var lambda; | ||
746 | |||
747 | f2m = this.finiteField(); | ||
748 | |||
749 | if (aPointA.x().compare(aPointB.x()) != 0) { | ||
750 | //console.log(" a.x != b.x"); | ||
751 | lambda =f2m.multiply( | ||
752 | f2m.add(aPointA.y(), aPointB.y()), | ||
753 | f2m.inverse(f2m.add(aPointA.x(), aPointB.x())) | ||
754 | ); | ||
755 | x = f2m.add(this.a(), f2m.multiply(lambda, lambda)); | ||
756 | x = f2m.add(x, lambda); | ||
757 | x = f2m.add(x, aPointA.x()); | ||
758 | x = f2m.add(x, aPointB.x()); | ||
759 | } else { | ||
760 | //console.log(" a.x == b.x"); | ||
761 | lambda = f2m.add(aPointB.x(), f2m.multiply(aPointB.y(), f2m.inverse(aPointB.x()))); | ||
762 | //console.log(" lambda: " + lambda.asString(16)); | ||
763 | x = f2m.add(this.a(), f2m.multiply(lambda, lambda)); | ||
764 | //console.log(" x (step 1): " + x.asString(16)); | ||
765 | x = f2m.add(x, lambda); | ||
766 | //console.log(" x (step 2): " + x.asString(16)); | ||
767 | } | ||
768 | |||
769 | y = f2m.multiply(f2m.add(aPointB.x(), x), lambda); | ||
770 | //console.log(" y (step 1): " + y.asString(16)); | ||
771 | y = f2m.add(y, x); | ||
772 | //console.log(" y (step 2): " + y.asString(16)); | ||
773 | y = f2m.add(y, aPointB.y()); | ||
774 | //console.log(" y (step 3): " + y.asString(16)); | ||
775 | |||
776 | result = new Clipperz.Crypto.ECC.BinaryField.Point({x:x, y:y}) | ||
777 | } | ||
778 | //console.log("<<< ECC.BinaryField.Curve.add"); | ||
779 | |||
780 | return result; | ||
781 | }, | ||
782 | |||
783 | //----------------------------------------------------------------------------- | ||
784 | |||
785 | 'multiply': function(aValue, aPoint) { | ||
786 | var result; | ||
787 | |||
788 | console.profile(); | ||
789 | result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O}); | ||
790 | |||
791 | if (aValue.isZero() == false) { | ||
792 | var k, Q; | ||
793 | var i; | ||
794 | var countIndex; countIndex = 0; | ||
795 | |||
796 | if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.WordArrayValue.O) > 0) { | ||
797 | k = aValue; | ||
798 | Q = aPoint; | ||
799 | } else { | ||
800 | MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!"); | ||
801 | k = aValue.negate(); | ||
802 | Q = this.negate(aPoint); | ||
803 | } | ||
804 | |||
805 | //console.log("k: " + k.toString(16)); | ||
806 | //console.log("k.bitSize: " + k.bitSize()); | ||
807 | for (i=k.bitSize()-1; i>=0; i--) { | ||
808 | result = this.add(result, result); | ||
809 | if (k.isBitSet(i)) { | ||
810 | result = this.add(result, Q); | ||
811 | } | ||
812 | |||
813 | // if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++; | ||
814 | } | ||
815 | } | ||
816 | console.profileEnd(); | ||
817 | |||
818 | return result; | ||
819 | }, | ||
820 | |||
821 | //----------------------------------------------------------------------------- | ||
822 | __syntaxFix__: "syntax fix" | ||
823 | }); | ||
824 | |||
825 | //############################################################################# | ||
826 | |||
827 | //############################################################################# | ||
828 | / * | ||
829 | Clipperz.Crypto.ECC.Key = function(args) { | ||
830 | args = args || {}; | ||
831 | |||
832 | return this; | ||
833 | } | ||
834 | |||
835 | Clipperz.Crypto.ECC.Key.prototype = MochiKit.Base.update(null, { | ||
836 | |||
837 | 'asString': function() { | ||
838 | return "Clipperz.Crypto.ECC.Key"; | ||
839 | }, | ||
840 | |||
841 | //----------------------------------------------------------------------------- | ||
842 | __syntaxFix__: "syntax fix" | ||
843 | }); | ||
844 | * / | ||
845 | //############################################################################# | ||
846 | |||
847 | |||
848 | //############################################################################# | ||
849 | |||
850 | Clipperz.Crypto.ECC.StandardCurves = {}; | ||
851 | |||
852 | MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, { | ||
853 | / * | ||
854 | '_K571': null, | ||
855 | 'K571': function() { | ||
856 | if (Clipperz.Crypto.ECC.StandardCurves._K571 == null) { | ||
857 | Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.Curve.Koblitz({ | ||
858 | exadecimalForm: '80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', | ||
859 | a: new Clipperz.Crypto.BigInt(0), | ||
860 | G: new Clipperz.Crypto.ECC.Point({ | ||
861 | x: new Clipperz.Crypto.BigInt('26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972', 16), | ||
862 | y: new Clipperz.Crypto.BigInt('349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3', 16) | ||
863 | }), | ||
864 | n: new Clipperz.Crypto.BigInt('1932268761508629172347675945465993672149463664853217499328617625725759571144780212268133978522706711834706712800825351461273674974066617311929682421617092503555733685276673', 16), | ||
865 | h: new Clipperz.Crypto.BigInt(4) | ||
866 | }); | ||
867 | } | ||
868 | |||
869 | return Clipperz.Crypto.ECC.StandardCurves._K571; | ||
870 | }, | ||
871 | * / | ||
872 | //----------------------------------------------------------------------------- | ||
873 | |||
874 | '_B571': null, | ||
875 | 'B571': function() { //f(z) = z^571 + z^10 + z^5 + z^2 + 1 | ||
876 | if (Clipperz.Crypto.ECC.StandardCurves._B571 == null) { | ||
877 | Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({ | ||
878 | modulus: new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16), | ||
879 | a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16), | ||
880 | b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a', 16), | ||
881 | G: new Clipperz.Crypto.ECC.BinaryField.Point({ | ||
882 | x: new Clipperz.Crypto.ECC.BinaryField.Value('0303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19', 16), | ||
883 | y: new Clipperz.Crypto.ECC.BinaryField.Value('037bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b', 16) | ||
884 | }), | ||
885 | // r: new Clipperz.Crypto.ECC.BinaryField.Value('3864537523017258344695351890931987344298927329706434998657235251451519142289560424536143999389415773083133881121926944486246872462816813070234528288303332411393191105285703', 10), | ||
886 | r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16), | ||
887 | h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16) | ||
888 | |||
889 | // S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10), | ||
890 | // n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16), | ||
891 | }); | ||
892 | |||
893 | //----------------------------------------------------------------------------- | ||
894 | // | ||
895 | //Guide to Elliptic Curve Cryptography | ||
896 | //Darrel Hankerson, Alfred Menezes, Scott Vanstone | ||
897 | //- Pag: 56, Alorithm 2.45 (with a typo!!!) | ||
898 | // | ||
899 | //----------------------------------------------------------------------------- | ||
900 | // | ||
901 | // http://www.milw0rm.com/papers/136 | ||
902 | // | ||
903 | // ------------------------------------------------------------------------- | ||
904 | // Polynomial Reduction Algorithm Modulo f571 | ||
905 | // ------------------------------------------------------------------------- | ||
906 | // | ||
907 | // Input: Polynomial p(x) of degree 1140 or less, stored as | ||
908 | // an array of 2T machinewords. | ||
909 | // Output: p(x) mod f571(x) | ||
910 | // | ||
911 | // FOR i = T-1, ..., 0 DO | ||
912 | // SET X := P[i+T] | ||
913 | // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15) | ||
914 | // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27) | ||
915 | // | ||
916 | // SET X := P[T-1] >> 27 | ||
917 | // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10) | ||
918 | // P[T-1] := P[T-1] & 0x07ffffff | ||
919 | // | ||
920 | // RETURN P[T-1],...,P[0] | ||
921 | // | ||
922 | // ------------------------------------------------------------------------- | ||
923 | // | ||
924 | Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) { | ||
925 | varresult; | ||
926 | varC, T; | ||
927 | var i; | ||
928 | |||
929 | //console.log(">>> binaryField.finiteField.(improved)module"); | ||
930 | // C = aValue.value().slice(0); | ||
931 | C = aValue._value.slice(0); | ||
932 | for (i=35; i>=18; i--) { | ||
933 | T = C[i]; | ||
934 | C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0); | ||
935 | C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0); | ||
936 | } | ||
937 | T = (C[17] >>> 27); | ||
938 | C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0); | ||
939 | C[17] = (C[17] & 0x07ffffff); | ||
940 | |||
941 | for(i=18; i<=35; i++) { | ||
942 | C[i] = 0; | ||
943 | } | ||
944 | |||
945 | result = new Clipperz.Crypto.ECC.BinaryField.WordArrayValue(C); | ||
946 | //console.log("<<< binaryField.finiteField.(improved)module"); | ||
947 | |||
948 | return result; | ||
949 | }; | ||
950 | } | ||
951 | |||
952 | return Clipperz.Crypto.ECC.StandardCurves._B571; | ||
953 | }, | ||
954 | |||
955 | //----------------------------------------------------------------------------- | ||
956 | __syntaxFix__: "syntax fix" | ||
957 | }); | ||
958 | |||
959 | //############################################################################# | ||
960 | */ | ||