init: v1.0.0
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
//go:build !gmp
|
||||
// +build !gmp
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/internal/randutil"
|
||||
)
|
||||
|
||||
type Int = big.Int
|
||||
|
||||
var bigOne = new(big.Int).SetInt64(1)
|
||||
|
||||
func FromBigInt(src *big.Int) *Int {
|
||||
return src
|
||||
}
|
||||
func IntoBigInt(src *Int) *big.Int {
|
||||
return src
|
||||
}
|
||||
|
||||
func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
|
||||
e := big.NewInt(int64(pub.E))
|
||||
c.Exp(m, e, pub.N)
|
||||
return c
|
||||
}
|
||||
|
||||
// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
|
||||
// random source is given, RSA blinding is used.
|
||||
func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
|
||||
// TODO(agl): can we get away with reusing blinds?
|
||||
if c.Cmp(priv.N) > 0 {
|
||||
err = ErrDecryption
|
||||
return
|
||||
}
|
||||
if priv.N.Sign() == 0 {
|
||||
return nil, ErrDecryption
|
||||
}
|
||||
|
||||
var ir *big.Int
|
||||
if random != nil {
|
||||
randutil.MaybeReadByte(random)
|
||||
|
||||
// Blinding enabled. Blinding involves multiplying c by r^e.
|
||||
// Then the decryption operation performs (m^e * r^e)^d mod n
|
||||
// which equals mr mod n. The factor of r can then be removed
|
||||
// by multiplying by the multiplicative inverse of r.
|
||||
|
||||
var r *big.Int
|
||||
ir = new(big.Int)
|
||||
for {
|
||||
r, err = rand.Int(random, priv.N)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// if r.Cmp(bigZero) == 0 {
|
||||
if r.Sign() == 0 {
|
||||
r = bigOne
|
||||
}
|
||||
ok := ir.ModInverse(r, priv.N)
|
||||
if ok != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
bigE := big.NewInt(int64(priv.E))
|
||||
rpowe := new(big.Int).Exp(r, bigE, priv.N) // N != 0
|
||||
cCopy := new(big.Int).Set(c)
|
||||
cCopy.Mul(cCopy, rpowe)
|
||||
cCopy.Mod(cCopy, priv.N)
|
||||
c = cCopy
|
||||
}
|
||||
|
||||
if priv.Precomputed.Dp == nil {
|
||||
m = new(big.Int).Exp(c, priv.D, priv.N)
|
||||
} else {
|
||||
// We have the precalculated values needed for the CRT.
|
||||
m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
|
||||
m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
|
||||
m.Sub(m, m2)
|
||||
if m.Sign() < 0 {
|
||||
m.Add(m, priv.Primes[0])
|
||||
}
|
||||
m.Mul(m, priv.Precomputed.Qinv)
|
||||
m.Mod(m, priv.Primes[0])
|
||||
m.Mul(m, priv.Primes[1])
|
||||
m.Add(m, m2)
|
||||
|
||||
for i, values := range priv.Precomputed.CRTValues {
|
||||
prime := priv.Primes[2+i]
|
||||
m2.Exp(c, values.Exp, prime)
|
||||
m2.Sub(m2, m)
|
||||
m2.Mul(m2, values.Coeff)
|
||||
m2.Mod(m2, prime)
|
||||
if m2.Sign() < 0 {
|
||||
m2.Add(m2, prime)
|
||||
}
|
||||
m2.Mul(m2, values.R)
|
||||
m.Add(m, m2)
|
||||
}
|
||||
}
|
||||
|
||||
if ir != nil {
|
||||
// Unblind.
|
||||
m.Mul(m, ir)
|
||||
m.Mod(m, priv.N)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user