Nicolas Cellier uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-nice.364.mcz ==================== Summary ==================== Name: System-nice.364 Author: nice Time: 28 August 2010, 9:47:42.86 pm UUID: 4318cbfe-643c-434c-92f6-274f7cfc387e Ancestors: System-cbc.363 Apply cosmetic refactorings described at http://lists.squeakfoundation.org/pipermail/squeak-dev/2008-July/130162.html Essentially reuse some existing Integer bit twiddling rather than re-inventing them. =============== Diff against System-cbc.363 =============== Item was changed: ----- Method: DigitalSignatureAlgorithm>>logOfLargestPowerOfTwoDividing: (in category 'private') ----- logOfLargestPowerOfTwoDividing: aPositiveInteger "Answer the base-2 log of the largest power of two that divides the given integer. For example, the largest power of two that divides 24 is 8, whose log base-2 is 3. Do this efficiently even when the given number is a large integer. Assume that the given integer is > 0." + "DigitalSignatureAlgorithm new logOfLargestPowerOfTwoDividing: (32 * 3)" - "DigitalSignatureAlgorithm new largestPowerOfTwoDividing: (32 * 3)" + ^aPositiveInteger lowBit - 1! - | digitIndex power d | - digitIndex := (1 to: aPositiveInteger digitLength) detect: [:i | (aPositiveInteger digitAt: i) ~= 0]. - power := (digitIndex - 1) * 8. - d := aPositiveInteger digitAt: digitIndex. - [d odd] whileFalse: [ - power := power + 1. - d := d bitShift: -1]. - ^ power - ! Item was changed: ----- Method: ThirtyTwoBitRegister>>leftRotateBy: (in category 'accumulator ops') ----- leftRotateBy: bits "Rotate my contents left by the given number of bits, retaining exactly 32 bits." "Details: Perform this operation with as little LargeInteger arithmetic as possible." | bitCount s1 s2 newHi | + "ensure bitCount is in range [0..31]" - "ensure bitCount is in range [0..32]" bitCount := bits \\ 32. - bitCount < 0 ifTrue: [bitCount := bitCount + 32]. - bitCount > 16 ifTrue: [ s1 := bitCount - 16. s2 := s1 - 16. newHi := ((low bitShift: s1) bitAnd: 16rFFFF) bitOr: (hi bitShift: s2). low := ((hi bitShift: s1) bitAnd: 16rFFFF) bitOr: (low bitShift: s2). hi := newHi] ifFalse: [ s1 := bitCount. s2 := s1 - 16. newHi := ((hi bitShift: s1) bitAnd: 16rFFFF) bitOr: (low bitShift: s2). low := ((low bitShift: s1) bitAnd: 16rFFFF) bitOr: (hi bitShift: s2). hi := newHi] ! Item was changed: ----- Method: DigitalSignatureAlgorithm>>inverseOf:mod: (in category 'large integer arithmetic') ----- inverseOf: x mod: n "Answer the inverse of x modulus n. That is, the integer y such that (x * y) \\ n is 1. Both x and n must be positive, and it is assumed that x < n and that x and n are integers." "Details: Use the extended Euclidean algorithm, Schneier, p. 247." + | v u u1 u2 u3 t1 t2 t3 tmp | - | v u k u1 u2 u3 t1 t2 t3 tmp | ((x <= 0) or: [n <= 0]) ifTrue: [self error: 'x and n must be greater than zero']. x >= n ifTrue: [self error: 'x must be < n']. v := x. u := n. + (x even and: [n even]) ifTrue: [self error: 'no inverse']. - k := 0. - [x even and: [n even and: [u > 0]]] whileTrue: [ "eliminate common factors of two" - k := k + 1. - u := u bitShift: -1. - v := v bitShift: -1]. u1 := 1. u2 := 0. u3 := u. t1 := v. t2 := u - 1. t3 := v. [ [u3 even ifTrue: [ ((u1 odd) or: [u2 odd]) ifTrue: [ u1 := u1 + v. u2 := u2 + u]. u1 := u1 bitShift: -1. u2 := u2 bitShift: -1. u3 := u3 bitShift: -1]. ((t3 even) or: [u3 < t3]) ifTrue: [ tmp := u1. u1 := t1. t1 := tmp. tmp := u2. u2 := t2. t2 := tmp. tmp := u3. u3 := t3. t3 := tmp]. u3 even and: [u3 > 0]] whileTrue: ["loop while u3 is even"]. [((u1 < t1) or: [u2 < t2]) and: [u1 > 0]] whileTrue: [ u1 := u1 + v. u2 := u2 + u]. u1 := u1 - t1. u2 := u2 - t2. u3 := u3 - t3. t3 > 0] whileTrue: ["loop while t3 > 0"]. [u1 >= v and: [u2 >= u]] whileTrue: [ u1 := u1 - v. u2 := u2 - u]. - u1 := u1 bitShift: k. - u2 := u2 bitShift: k. - u3 := u3 bitShift: k. - u3 = 1 ifFalse: [self error: 'no inverse']. ^ u - u2 ! Item was changed: ----- Method: DigitalSignatureAlgorithm>>isProbablyPrime: (in category 'large integer arithmetic') ----- isProbablyPrime: p "Answer true if p is prime with very high probability. Such a number is sometimes called an 'industrial grade prime'--a large number that is so extremely likely to be prime that it can assumed that it actually is prime for all practical purposes. This implementation uses the Rabin-Miller algorithm (Schneier, p. 159)." | iterations factor pMinusOne b m r a j z couldBePrime | iterations := 50. "Note: The DSA spec requires >50 iterations; Schneier says 5 are enough (p. 260)" "quick elimination: check for p divisible by a small prime" SmallPrimes ifNil: [ "generate list of small primes > 2" SmallPrimes := Integer primesUpTo: 2000. SmallPrimes := SmallPrimes copyFrom: 2 to: SmallPrimes size]. factor := SmallPrimes detect: [:f | (p \\ f) = 0] ifNone: [nil]. factor ifNotNil: [^ p = factor]. pMinusOne := p - 1. b := self logOfLargestPowerOfTwoDividing: pMinusOne. + m := pMinusOne bitShift: b negated. - m := pMinusOne // (2 raisedTo: b). "Assert: pMinusOne = m * (2 raisedTo: b) and m is odd" Transcript show: ' Prime test pass '. r := Random new. 1 to: iterations do: [:i | Transcript show: i printString; space. a := (r next * 16rFFFFFF) truncated. j := 0. z := (a raisedTo: m modulo: p) normalize. couldBePrime := z = 1. [couldBePrime] whileFalse: [ z = 1 ifTrue: [Transcript show: 'failed!!'; cr. ^ false]. "not prime" z = pMinusOne ifTrue: [couldBePrime := true] ifFalse: [ (j := j + 1) < b ifTrue: [z := (z * z) \\ p] ifFalse: [Transcript show: 'failed!!'; cr. ^ false]]]]. "not prime" Transcript show: 'passed!!'; cr. ^ true "passed all tests; probably prime" ! |
Free forum by Nabble | Edit this page |