Montgomery reduction: Difference between revisions

m
→‎{{header|Go}}: removed timing
m (→‎{{header|Tcl}}: mark as in progress)
m (→‎{{header|Go}}: removed timing)
Line 110:
"fmt"
"math/big"
"math/rand"
"time"
)
 
// mont holds numbers useful for working in Mongomery representation.
type mont struct {
n uint // m.BitLen()
m *big.Int // modulus, must be odd
r2 *big.Int // (1<<2n) mod m
}
 
// constructor
func newMont(m *big.Int) *mont {
Line 145:
}
return a
}
 
// example use:
func main() {
Line 194:
 
// and demonstrate a use:
fmt.Println("\nMontgomery computation of x1 ^ x2 mod m:", f())
show("\nLibrary:", func() *big.Int {
// this is the modular exponentiation algorithm, except we call
return new(big.Int).Exp(x1, x2, m)
// mont.reduce instead of using a mod function.
})
prod := mr.reduce(mr.r2) // 1
show("\nMontgomery:", func() *big.Int {
base := mr.reduce(baset1.Mul(basex1, basemr.r2)) // x1^1
// this is the modular exponentiation algorithm, except we call
exp := new(big.Int).Set(x2) // not reduced
// mont.reduce instead of using a mod function.
for prod := mrexp.reduceBitLen(mr.r2) > 0 // 1{
baseif := mrexp.reduceBit(t1.Mul(x1, mr.r2)0) //== x1^1 {
prod = mr.reduce(prod.Mul(prod, base))
exp := new(big.Int).Set(x2) // not reduced
for exp.BitLen() > 0 {
if exp.Bit(0) == 1 {
prod = mr.reduce(prod.Mul(prod, base))
}
exp.Rsh(exp, 1)
base = mr.reduce(base.Mul(base, base))
}
return mrexp.reduceRsh(prodexp, 1)
base = mr.reduce(base.Mul(base, base))
})
} }
fmt.Println(timemr.Nowreduce().Sub(t0prod))
 
// show library-based equivalent computation as a check
func show(heading string, f func() *big.Int) {
fmt.Println(heading"\nLibrary-based computation of x1 ^ x2 mod m:")
return fmt.Println(new(big.Int).Exp(x1, x2, m))
t0 := time.Now()
fmt.Println("x1 ^ x2 mod m:", f())
fmt.Println(time.Now().Sub(t0))
}</lang>
{{out}}
Output:
<pre>
b: 2
n: 100
r: 1267650600228229401496703205376
m: 750791094644726559640638407699
m: 1191151171693032142151966564621
t1: 323165824550862327179367294465482435542970161392400401329100
t1: 138602318824179275477121611740471794618999274340657947731554
t2: 308607334419945011411837686695175944083084270671482464168730
t2: 397645077922552596057001924720561733079744309909810064024787
r1: 440160025148131680164261562101
r1: 1073769066977456952449715239458
r2: 435362628198191204145287283255
r2: 460620928979319347925360938242
 
Original x1: 141982853055250888109454150154540019781128412936473322405310
Recovererd from r1: 141982853055250888109454150154540019781128412936473322405310
Original x2: 407343709295665106703621643087515692107665463680305819378593
Recovererd from r2: 407343709295665106703621643087515692107665463680305819378593
 
Montgomery computation of x1 ^ x2 mod m:
Library:
151232511393500655853002423778
x1 ^ x2 mod m: 599840174322403511400105423249
231us
 
Library based computation of x1 ^ x2 mod m:
Montgomery:
151232511393500655853002423778
x1 ^ x2 mod m: 599840174322403511400105423249
2.316ms
</pre>
 
1,707

edits