[Tkabber-dev] r2087 - in trunk/tkabber-plugins: . otr otr/tclotr

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Fri Jan 24 22:02:20 MSK 2014


Author: sergei
Date: 2014-01-24 22:02:20 +0400 (Fri, 24 Jan 2014)
New Revision: 2087

Modified:
   trunk/tkabber-plugins/ChangeLog
   trunk/tkabber-plugins/otr/key.tcl
   trunk/tkabber-plugins/otr/tclotr/crypto.tcl
Log:
	* otr/key.tcl, otr/tclotr/crypto.tcl: Implemented generating new
	  DSA private key.


Modified: trunk/tkabber-plugins/ChangeLog
===================================================================
--- trunk/tkabber-plugins/ChangeLog	2014-01-24 05:59:57 UTC (rev 2086)
+++ trunk/tkabber-plugins/ChangeLog	2014-01-24 18:02:20 UTC (rev 2087)
@@ -4,6 +4,9 @@
 	  given connection if the associated private key is imported or
 	  deleted.
 
+	* otr/key.tcl, otr/tclotr/crypto.tcl: Implemented generating new
+	  DSA private key.
+
 2014-01-23  Sergei Golovan <sgolovan at nes.ru>
 
 	* otr/otr.tcl, otr/tclotr/message.tcl, otr/tclotr/otr.tcl: Code

Modified: trunk/tkabber-plugins/otr/key.tcl
===================================================================
--- trunk/tkabber-plugins/otr/key.tcl	2014-01-24 05:59:57 UTC (rev 2086)
+++ trunk/tkabber-plugins/otr/key.tcl	2014-01-24 18:02:20 UTC (rev 2087)
@@ -205,7 +205,7 @@
 		-command [namespace code [list export_key $w]]
     grid $f.export -row 4 -column 1 -sticky nsew
 
-    button $f.gen -text [::msgcat::mc "Generate new key"] -state disabled \
+    button $f.gen -text [::msgcat::mc "Generate new key"] \
 		-command [namespace code [list generate_key $w]]
     grid $f.gen -row 5 -column 0 -sticky nsew
 
@@ -214,7 +214,7 @@
     grid $f.delete -row 5 -column 1 -sticky nsew
 
     ProgressBar $f.pb -variable [namespace current]::progress \
-		      -maximum 50 \
+		      -maximum 10000 \
 		      -type infinite
     grid $f.pb -row 6 -column 0 -columnspan 2 -sticky ew
 
@@ -248,8 +248,7 @@
 	set fingerprint $res
 	$f.import configure -state normal
 	$f.export configure -state normal
-	# TODO: generate new key
-	#$f.gen configure -state normal
+	$f.gen configure -state normal
 	$f.delete configure -state normal
     join $res
     } else {
@@ -258,8 +257,7 @@
 	set fingerprint ""
 	$f.import configure -state normal
 	$f.export configure -state disabled
-	# TODO: generate new key
-	#$f.gen configure -state normal
+	$f.gen configure -state normal
 	$f.delete configure -state disabled
     }
 }
@@ -310,9 +308,86 @@
     fill_dialog $w
 }
 
-proc key::gen_key {w} {
+proc key::generate_key {w} {
     variable Keys
     variable keyjid
+    variable progress
 
-    # TODO
+    set L 1024
+    set N 160
+
+    $w itemconfigure 0 -state disabled
+    set f [$w getframe]
+    $f.jid configure -state disabled
+    $f.import configure -state disabled
+    $f.export configure -state disabled
+    $f.gen configure -state disabled
+    $f.delete configure -state disabled
+
+    set status 0
+    while {!$status} {
+	# Generate first seed
+	set fstatus 0
+	while {!$fstatus} {
+	    lassign [::otr::crypto::getFirstSeed $N $N] \
+		    fstatus firstseed
+	    update
+	}
+	incr progress
+
+	set qstatus 0
+	while {!$qstatus} {
+	    lassign [::otr::crypto::genPrimesInit $N $firstseed] \
+		    qstatus q qseed qgen_counter
+	    update
+	}
+	incr progress
+
+	set pstatus 0
+	while {!$pstatus} {
+	    lassign [::otr::crypto::genPrimesCont $L $qseed] \
+		    pstatus p0 pseed pgen_counter
+	    update
+	}
+	incr progress
+
+	set outlen 256
+	set iterations [expr {[::otr::crypto::Ceil $L $outlen]-1}]
+	set old_counter $pgen_counter
+	set x 0
+	set mult 1
+	for {set i 0} {$i <= $iterations} {incr i} {
+	    incr x [expr {[::otr::crypto::Bits2Int \
+				[::sha2::sha256 -bin \
+				    [::otr::crypto::Int2Octets $pseed]]] * $mult}]
+	    incr pseed
+	    set mult [expr {$mult * 2**$outlen}]
+	}
+	set x [expr {2**($L-1) + ($x % (2**($L-1)))}]
+	set t [::otr::crypto::Ceil $x [expr {2*$q*$p0}]]
+
+	while {$pgen_counter <= 4*$L+$old_counter} {
+	    lassign [::otr::crypto::genPrimesIteration \
+			    $L $t $q $p0 $pseed $pgen_counter] \
+		    status t p q pseed pgen_counter
+	    if {$status} {
+		break
+	    }
+	    incr progress
+	    update
+	}
+    }
+
+    set g [::otr::crypto::genGenerator $p $q]
+    incr progress
+    update
+    lassign [::otr::crypto::genKeyPair $p $q $g] kstatus x y
+    incr progress
+    update
+    dict set Keys $keyjid [list $p $q $g $y $x]
+    store $Keys
+    [namespace parent]::clear_all_jid $keyjid
+    fill_dialog $w
+    $w itemconfigure 0 -state normal
+    $f.jid configure -state normal
 }

Modified: trunk/tkabber-plugins/otr/tclotr/crypto.tcl
===================================================================
--- trunk/tkabber-plugins/otr/tclotr/crypto.tcl	2014-01-24 05:59:57 UTC (rev 2086)
+++ trunk/tkabber-plugins/otr/tclotr/crypto.tcl	2014-01-24 18:02:20 UTC (rev 2087)
@@ -231,7 +231,7 @@
     while {$r == 0 || $s == 0} {
         if {$random == 0} {
             while {$k == 0} {
-                set k [expr {[random $qlen] % $q}]
+                set k [expr {[random [expr {$qlen+64}]] % ($q-1) + 1}]
             }
         } else {
             set k $random ; # For testing purposes only
@@ -511,7 +511,7 @@
 #       b           Positive integer.
 #
 # Result:
-#       Tuple {x y} where x = GCD(a,b), y is such that y*b mod a = x.
+#       Tuple {x y} where x*a+y*b = GCD(a,b).
 #
 # Side effects:
 #       None.
@@ -526,4 +526,227 @@
     }
 }
 
+# ::otr::crypto::getFirstSeed --
+
+proc ::otr::crypto::getFirstSeed {N seedlen} {
+    switch -- $N {
+        160 - 224 - 256 {}
+        default { return {0 0} }
+    }
+
+    if {$seedlen < $N} {
+        return {0 0}
+    }
+
+    set firstseed [random $seedlen]
+    if {$firstseed < 2**($N-1)} {
+        incr firstseed [expr {2**($N-1)}]
+    }
+    return [list 1 $firstseed]
+}
+
+# ::otr::crypto::testPrime --
+
+proc ::otr::crypto::testPrime {n} {
+    if {$n > 2 && $n % 2 == 0} {
+        return 0
+    }
+    for {set k 3} {$k*$k <= $n} {incr k 2} {
+        if {$n % $k == 0} {
+            return 0
+        }
+    }
+    return 1
+}
+
+# ::otr::crypto::Ceil --
+
+proc ::otr::crypto::Ceil {k n} {
+    expr {($k+$n-1)/$n}
+}
+
+# ::otr::crypto::randomPrime --
+
+proc ::otr::crypto::randomPrime {length input_seed} {
+    if {$length < 2} {
+        return {0}
+    }
+    if {$length < 33} {
+        set prime_seed $input_seed
+        set prime_gen_counter 0
+        while {$prime_gen_counter <= 4*$length} {
+            set c [Bits2Int [Xor [::sha2::sha256 -bin [Int2Octets $prime_seed]] \
+                                 [::sha2::sha256 -bin [Int2Octets [expr {$prime_seed+1}]]]]]
+            set c [expr {2**($length-1) + ($c % (2**($length-1)))}]
+            set c [expr {($c % 2 == 0)? $c+1 : $c}]
+            incr prime_gen_counter
+            incr prime_seed 2
+            if {[testPrime $c]} {
+                return [list 1 $c $prime_seed $prime_gen_counter]
+            }
+        }
+        return {0}
+    } else {
+        lassign [randomPrime [Ceil $length 2] $input_seed] status c0 prime_seed prime_gen_counter
+        if {!$status} {
+            return {0}
+        }
+        set outlen 256
+        set iterations [expr {[Ceil $length $outlen]-1}]
+        set old_counter $prime_gen_counter
+        set x 0
+        set mult 1
+        for {set i 0} {$i <= $iterations} {incr i} {
+            incr x [expr {[Bits2Int [::sha2::sha256 -bin [Int2Octets $prime_seed]]] * $mult}]
+            incr prime_seed
+            set mult [expr {$mult * 2**$outlen}]
+        }
+        set x [expr {2**($length-1) + ($x % (2**($length-1)))}]
+        set t [Ceil $x [expr {2*$c0}]]
+
+        while {$prime_gen_counter < 4*$length+$old_counter} {
+            if {2*$t*$c0+1 > 2**$length} {
+                set t [Ceil [expr {2**($length-1)}] [expr {2*$c0}]]
+            }
+            set c [expr {2*$t*$c0+1}]
+            incr prime_gen_counter
+
+            set a 0
+            set mult 1
+            for {set i 0} {$i <= $iterations} {incr i} {
+                incr a [expr {[Bits2Int [::sha2::sha256 -bin [Int2Octets $prime_seed]]] * $mult}]
+                incr prime_seed
+                set mult [expr {$mult * 2**$outlen}]
+            }
+            set a [expr {2+($a % ($c-3))}]
+            set z [Power $c $a [expr {2*$t}]]
+
+            lassign [EGCD $c [expr {$z-1}]] xx yy
+            set pow [Power $c $z $c0]
+            if {$xx*$c + $yy*($z-1) == 1 && $pow == 1} {
+                return [list 1 $c $prime_seed $prime_gen_counter]
+            }
+            incr t
+        }
+        return {0}
+    }
+}
+
+# ::otr::crypto::genPrimes --
+
+proc ::otr::crypto::genPrimes {L N firstseed} {
+    switch -- $L/$N {
+        1024/160 - 2048/224 - 2048/256 - 3072/256 {}
+        default {
+            return {0}
+        }
+    }
+
+    lassign [genPrimesInit $N $firstseed] qstatus q qseed qgen_counter
+    if {!$qstatus} {
+        return {0}
+    }
+
+    lassign [genPrimesCont $L $qseed] pstatus p0 pseed pgen_counter
+    if {!$pstatus} {
+        return {0}
+    }
+
+    set outlen 256
+    set iterations [expr {[Ceil $L $outlen]-1}]
+    set old_counter $pgen_counter
+    set x 0
+    set mult 1
+    for {set i 0} {$i <= $iterations} {incr i} {
+        incr x [expr {[Bits2Int [::sha2::sha256 -bin [Int2Octets $pseed]]] * $mult}]
+        incr pseed
+        set mult [expr {$mult * 2**$outlen}]
+    }
+    set x [expr {2**($L-1) + ($x % (2**($L-1)))}]
+    set t [Ceil $x [expr {2*$q*$p0}]]
+
+    while {$pgen_counter <= 4*$L+$old_counter} {
+        lassign [genPrimesIteration $L $t $q $p0 $pseed $pgen_counter] \
+                status t p q pseed pgen_counter
+        if {$status} {
+            return [list 1 $p $q $pseed $qseed $pgen_counter $qgen_counter]
+        }
+    }
+    return {0}
+}
+
+# ::otr::primes::genPrimesInit --
+
+proc ::otr::crypto::genPrimesInit {N firstseed} {
+    randomPrime $N $firstseed
+}
+
+# ::otr::crypto::genPrimesCont --
+
+proc ::otr::crypto::genPrimesCont {L qseed} {
+    randomPrime [expr {[Ceil $L 2]+1}] $qseed
+}
+
+# ::otr::crypto::genPrimesIteration --
+
+proc ::otr::crypto::genPrimesIteration {L t q p0 pseed pgen_counter} {
+    if {2*$t*$q*$p0+1 > 2**$L} {
+        set t [Ceil [expr {2**($L-1)}] [expr {2*$q*$p0}]]
+    }
+    set p [expr {2*$t*$q*$p0+1}]
+    incr pgen_counter
+
+    set outlen 256
+    set iterations [expr {[Ceil $L $outlen]-1}]
+    set a 0
+    set mult 1
+    for {set i 0} {$i <= $iterations} {incr i} {
+        incr a [expr {[Bits2Int [::sha2::sha256 -bin [Int2Octets $pseed]]] * $mult}]
+        incr pseed
+        set mult [expr {$mult * 2**$outlen}]
+    }
+    set a [expr {2+($a % ($p-3))}]
+    set z [Power $p $a [expr {2*$t*$q}]]
+
+    lassign [EGCD $p [expr {$z-1}]] xx yy
+    set pow [Power $p $z $p0]
+    if {$xx*$p + $yy*($z-1) == 1 && $pow == 1} {
+        return [list 1 $t $p $q $pseed $pgen_counter]
+    }
+    incr t
+    return [list 0 $t $p $q $pseed $pgen_counter]
+}
+
+# ::otr::crypto::genGenerator --
+
+proc ::otr::crypto::genGenerator {p q} {
+    set e [expr {($p-1)/$q}]
+    set g 1
+    set l [BitLength $p]
+    while {$g == 1} {
+        set h [expr {2+([random $l] % ($p-3))}]
+        set g [Power $p $h $e]
+    }
+    set g
+}
+
+# ::otr::crypto::genKeyPair --
+
+proc ::otr::crypto::genKeyPair {p q g} {
+    set L [BitLength $p]
+    set N [BitLength $q]
+
+    switch -- $L/$N {
+        1024/160 - 2048/224 - 2048/256 - 3072/256 {}
+        default {
+            return {0}
+        }
+    }
+
+    set c [random [expr {$N+64}]]
+    set x [expr {$c % ($q-1) + 1}]
+    set y [Power $p $g $x]
+    return [list 1 $x $y]
+}
+
 # vim:ts=8:sw=4:sts=4:et



More information about the Tkabber-dev mailing list